Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross apply MSSQL operator equivalent in bigquery

is there an equivalent to cross apply in Sql server syntaxe or in bigquery syntaxe.

I need to write this query without the cross apply:

   select *
    from t1 
    cross apply (select top 1 col1,col2,col3
    from t2
    where col1 = t1.col1
    and (col2 = '0' or col2 = t1.col2)
and (col3 = '0' or (col3 = left(t1.col3)  and t1.col4 = 'fr'))
    order by col2 desc, col3 desc)

t1 called 'Delivery' contains deliveries informations:

Delivery_ID,Delivery_ShipmentDate,Country_Code,address_ZipCode and the providerservice_id

t2 called 'ProviderService' contains informations about the providerservice:

Providerservice_id,DCountry_ID , DZone_Code  as well as a numeric ProviderService_DeliveryTime.

So each Delivery_ID has a ProviderService_ID And For the same Providerservice we could have several distinct ProviderService_DeliveryTime according to the other columns in this table(DCountry_ID , DZone_Code)

So the final query will be:

    Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime
    from Delivery t1
    cross apply (select top 1 ProviderService_DeliveryTime,DCountry_ID , DZone_Code 
from ProviderService 
    where ProviderService_id = t1.ProviderService_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR'))
        order by t2.DCountry_ID desc, t2.DZone_Code desc)sq

In fact I need first to write the same query in sql server syntaxe and then to write it in Bigquery because BigQuery don't recognize "cross apply" operator.

I tried to do it with row_number window function but it did not work:

    with cte as (Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime,row_number() over (partition by t2.providerservice_id order by t2.DCountry_ID desc, t2.DZone_Code desc) as num
    from Delivery t1
    inner join providerservice t2 on t1.providerservice_id = t2.providerservice_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR')))


select * from cte where num = 1

it works only when I filter by delivery_id:

 with cte as (Select t1.Delivery_ShipmentDate,t2.ProviderService_DeliveryTime,row_number() over (partition by t2.providerservice_id order by t2.DCountry_ID desc, t2.DZone_Code desc) as num
    from Delivery t1
    inner join providerservice t2 on t1.providerservice_id = t2.providerservice_id
And (DCountry_ID = '0' or DCountry_ID = t1.Country_Code)
And (DZone_Code = '0' or (DZone_Code = left(t1.address_ZipCode,2) and t1.Country_Code='FR'))
where delivery_id = xxxx)


select * from cte where num = 1

Can any one help me please? Thanks!!

like image 667
user3569267 Avatar asked Oct 30 '25 04:10

user3569267


2 Answers

Below is for BigQuery Standard SQL

#standardSQL
SELECT * EXCEPT(pos)
FROM (
  SELECT *
    ROW_NUMBER() OVER(PARTITION BY TO_JSON_STRING(t1) ORDER BY t2.col2 DESC, t2.col3 DESC) pos
  FROM t1 INNER JOIN t2
  ON t2.col1 = t1.col1
  AND (t2.col2 = '0' OR t2.col2 = t1.col2)
  AND (t2.col3 = '0' OR (t2.col3 = left(t1.col3)  AND t1.col4 = 'fr'))
)
WHERE pos = 1

I wish you gave us some data to play with - but having absence of it - above is just quick shot for you to try

I checked this approach (of implementing CROSS APPLY in BigQuery) against classic example with customers and orders tables and it worked

like image 104
Mikhail Berlyant Avatar answered Nov 01 '25 17:11

Mikhail Berlyant


Would correlated subquery work the same as cross apply?

   select *
    from t1 , (select col1,col2,col3
    from t2
    where col1 = t1.col1
    and (col2 = '0' or col2 = t1.col2)
and (col3 = '0' or (col3 = left(t1.col3)  and t1.col4 = 'fr'))
    order by col2 desc, col3 desc
    limit 1)
like image 45
Yun Zhang Avatar answered Nov 01 '25 18:11

Yun Zhang