Перекрестный эквивалент MSSQL-оператора в bigquery - PullRequest
1 голос
/ 26 марта 2019

существует ли эквивалент для перекрестного применения в синтаксисе сервера Sql или в синтаксисе bigquery.

Мне нужно написать этот запрос без применения кросс:

   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 под названием «Доставка» содержит информацию о доставке:

Delivery_ID,Delivery_ShipmentDate,Country_Code,address_ZipCode and the providerservice_id

t2, называемый «ProviderService», содержит информацию о сервисе провайдера:

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

Таким образом, каждый Delivery_ID имеет ProviderService_ID И для одного и того же Providerservice у нас может быть несколько отдельных ProviderService_DeliveryTime в соответствии с другими столбцами в этой таблице (DCountry_ID, DZone_Code)

Таким образом, окончательный запрос будет:

    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

Фактически мне нужно сначала написать тот же запрос в синтаксисе сервера SQL, а затем написать его в Bigquery, потому что BigQuery не распознает оператор перекрестного применения.

Я пытался сделать это с помощью функции окна row_number, но это не сработало:

    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

это работает только когда я фильтрую по 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

Может кто-нибудь помочь мне, пожалуйста? Спасибо !!

Ответы [ 2 ]

1 голос
/ 27 марта 2019

Ниже для 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

Хотелось бы, чтобы вы дали нам некоторые данные для игры - но при их отсутствии - просто быстрый способ попробовать

Я проверил этот подход (реализации CROSS APPLY в BigQuery) на классическом примере с таблицами клиентов и заказов, и он сработал

1 голос
/ 27 марта 2019

Будет ли коррелированный подзапрос работать так же, как перекрестное применение ?

   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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...