Почему standardql Bigquery возвращает несколько строк, а legacysql - только одну?

Не могли бы вы немного помочь мне с вопросом о синтаксисе standardql Bigquery, пожалуйста? Я пытаюсь понять, почему (и как это исправить) этот запрос standardql возвращает 2 строки, в то время как этот legacysql возвращает только 1 (а я ожидаю только одну).

StandardSQL

  SELECT 
  hits2.transaction.transactionId as transactionId
  FROM `ga-export-TTTT.1234567890.ga_sessions_*`
  ,UNNEST (hits) as hits2

WHERE 
hits2.transaction.transactionId = '03971163'

LegacySQL

select
hits.transaction.transactionId
FROM
 TABLE_DATE_RANGE([ga-export-TTTT:1234567890.ga_sessions_], TIMESTAMP('2016-09-01'), TIMESTAMP('2017-02-14'))
WHERE 
hits.transaction.transactionId = '03971163'

Прочитав справку, я также попробовал этот StandardSQL с теми же двумя строками в результатах:

select 
title
from
(
  SELECT
    ARRAY(SELECT transaction.transactionId FROM UNNEST(hits)
          WHERE transaction.transactionId = '03971163') AS title
  FROM `ga-export-TTTTT.1234567890.ga_sessions_*`
  )
WHERE ARRAY_LENGTH(title) > 0;

Был бы признателен за любую помощь в этом.


person user912830823    schedule 23.02.2017    source источник


Ответы (2)


Попробуйте вместо этого:

#standardSQL
SELECT 
  ARRAY(SELECT transaction.transactionId
        FROM UNNEST(hits)
        WHERE transaction.transactionId = '03971163')
    AS transactionIds
FROM `ga-export-TTTT.1234567890.ga_sessions_*`;

Когда вы используете CROSS JOIN с массивом, вы получаете строку в результате для каждого элемента массива. Если вам нужно однозначное соответствие со строками в таблице, вы можете использовать подзапрос массива (как в запросе выше), чтобы «переупаковать» элементы массива после применения фильтра. В качестве другого примера вы можете использовать подзапрос ARRAY вместе с SELECT AS STRUCT:

#standardSQL
SELECT 
  ARRAY(SELECT AS STRUCT transaction.*
        FROM UNNEST(hits)
        WHERE transaction.transactionId = '03971163')
    AS transactions
FROM `ga-export-TTTT.1234567890.ga_sessions_*`;

Это вернет массив всех полей внутри transaction для совпадений, соответствующих условию transaction.transactionId = '03971163'. Если вам нужен только один элемент массива, вы можете вместо этого использовать подзапрос в списке выбора с LIMIT:

#standardSQL
SELECT 
 (SELECT transaction.transactionId
  FROM UNNEST(hits)
  WHERE transaction.transactionId = '03971163'
  LIMIT 1)
    AS transactionId
FROM `ga-export-TTTT.1234567890.ga_sessions_*`;

Or:

#standardSQL
SELECT 
 (SELECT transaction
  FROM UNNEST(hits)
  WHERE transaction.transactionId = '03971163'
  LIMIT 1)
    AS transaction
FROM `ga-export-TTTT.1234567890.ga_sessions_*`;
person Elliott Brossard    schedule 23.02.2017
comment
Спасибо @Elliott. К сожалению, это не работает. Оба примера возвращают огромное количество строк, но должна быть только одна. - person user912830823; 23.02.2017
comment
Предоставленный мной запрос возвращает все элементы этого массива, соответствующие идентификатору транзакции, о чем вы и просили. Если вам нужен только один элемент массива, используйте вместо него LIMIT; см. мое редактирование. - person Elliott Brossard; 23.02.2017
comment
Привет, @Elliot, мой вопрос был о том, как получить результаты, аналогичные тем, которые я получаю при использовании legacysql. Использование Лимита 1 в этом случае не сработает. - person user912830823; 23.02.2017
comment
Вы не указали в своем вопросе действительный устаревший SQL-запрос, поэтому я не знаю, каких результатов вы ожидали. - person Elliott Brossard; 23.02.2017
comment
Ты прав! Извините, скопировал неправильный фрагмент кода. Просто обновил устаревший sql в запросе. @Эллиот - person user912830823; 23.02.2017
comment
Мне, должно быть, чего-то не хватает - либо ваш устаревший запрос SQL давал вам более одной строки, либо последний запрос, который я предоставил, все равно будет работать, если вы удалите LIMIT 1. Также необходимо выполнить фильтрацию по _TABLE_SUFFIX BETWEEN '2016-09-01' AND '2017-02-14'. - person Elliott Brossard; 23.02.2017

Единственная разница в ваших двух запросах (для устаревшей и стандартной версии SQL), которую я вижу, заключается в том, что вы потенциально запрашиваете другой набор таблиц!

В Legacy SQL Version - вы ограничиваете список таблиц для периода времени от TIMESTAMP ('2016-09-01') до TIMESTAMP ('2017-02-14'), тогда как в Standard SQL вы запрашиваете все таблицы ga_sessions_ в ga-export-TTTT.1234567890 наборе данных

Попробуйте ниже отфильтровать таблицы в тот же список, что и в Legacy SQL

#standardSQL
SELECT hits2.transaction.transactionId as transactionId
FROM `ga-export-TTTT.1234567890.ga_sessions_*`, UNNEST (hits) as hits2
WHERE hits2.transaction.transactionId = '03971163'
AND _TABLE_SUFFIX BETWEEN '20160901' AND '20170214'
person Mikhail Berlyant    schedule 23.02.2017