Первый вопрос StackOverflow и только начало работы с SQL и BigQuery.
В BigQuery у меня есть проект с одной таблицей: table
.
Эта таблица содержит:
некоторые данные x
,
некоторые временные метки для каждой записи time
,
- некоторые идентификаторы группы group
, которые разбивают записи,
- и столбец INTEGER
с именем rank
со всеми значениями NULL
.
Я хочу использовать UPDATE
, чтобы изменить эти NULL
значения:
rank
должен представлять ранг каждой строки в соответствующем group
на основе time
в порядке возрастания(rank=1
для самой ранней x
записи в группе, rank=2
для следующей и т. Д.)
Вот как я задаю запрос:
UPDATE project.table
SET table.rank = (
WITH temp AS (select *, GENERATE_UUID() AS id FROM project.table),
rank1 AS (
SELECT * , RANK() OVER(PARTITION BY group ORDER BY time ASC)
AS rankvalue FROM temp
)
SELECT rank1.rankvalue
FROM temp INNER JOIN rank1 ON temp.id=rank1.id
)
WHERE table.rank IS NULL
Запрос выполняется без ошибок, и BigQuery сообщает, что все строки были изменены, как и ожидалось.Но когда я проверяю, все значения rank
все еще NULL
.
Поскольку я проверил, что rankvalue
генерируется, как и ожидалось, я предполагаю, что в операторе JOIN
есть какая-то проблема.
Хотя я проверил, что rank1
действительно наследует от temp
всех id
, которые я создал.Поэтому я не понимаю, почему JOIN
терпит неудачу.
ALTERNATIVE:
Я попробовал альтернативный способ сделать это: я попытался first , присвоив уникальный идентификатор строки table
, вызывается id
, а затем используется следующий запрос:
UPDATE project.table
SET table.rank = (
WITH rank1 AS (
SELECT * , RANK() OVER(PARTITION BY group ORDER BY time ASC)
AS rankvalue FROM project.table
)
SELECT rank1.rankvalue
FROM project.table INNER JOIN rank1 ON table.id=rank1.id
)
WHERE table.rank IS NULL
Но этот запрос возвращает ошибку: Scalar subquery produced more than one element
.Я не могу понять почему, так как я проверил, что подзапрос WITH / SELECT / FROM возвращает ровно столько же строк, сколько есть в table
.
Любые заголовки очень приветствуются.
ОБНОВЛЕНИЕ:
Я попробовал следующее, и это сработало:
UPDATE project.table
SET table.rank = (
WITH rank1 AS (
SELECT * , RANK()
OVER(
PARTITION BY group
ORDER BY time AS
) AS rankvalue
FROM project.table)
SELECT rank1.rankvalue
FROM rank1 WHERE
table.id=rank1.id
)
WHERE TRUE
Что является модификацией второго варианта, который я пробовал ранее.Вопрос: работает ли он сейчас, потому что WHERE table.id=rank1.id
выбирает каждого отдельного table.id
, соответствующего каждому table.rank
, который проходит обновление, и сопоставляет его с соответствующим rank.id
(то есть выбирает одну строкув RHS для каждой строки в LHS), тогда как project.table INNER JOIN rank1 ON table.id=rank1.id
будет возвращать всю объединенную таблицу для каждого значения из table.rank
, которое подвергается обновлению (т.е. несколько строк в RHS для каждой строки вLHS)?