Подскажите с запросом к BigQuery (SQL)
От: VmK  
Дата: 24.01.20 13:10
Оценка:
Добрый день!

Что-то торможу жестко...

Вот есть таблица, которая хранит свойства некого объекта вместе с историей их изменений:

update_id key value
1 x 2
2 y 1
3 z 8
4 x 7
5 x 5
6 y 2

Какой нужно сделать SELECT, чтобы получить все свойства объекта с их самыми последними значениями?

Т.е. чтобы после запроса получилось:

update_id key value
3 z 8
5 x 5
6 y 2

Подскажите плиз кто знает, как должен выглядеть такой запрос? Уже всю голову сломал
Re: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 24.01.20 13:36
Оценка:
Здравствуйте, VmK, Вы писали:

VmK>Какой нужно сделать SELECT, чтобы получить все свойства объекта с их самыми последними значениями?


Для каждого key вытаскиваешь максимальный update_id. Затем вытаскиваешь строки по найденным id

Что-то тип такого (не проверял):

SELECT * 
FROM table
WHERE id IN (
  SELECT MAX(update_id)
  FROM table
  GROUP BY key
)
Best regards, Буравчик
Отредактировано 24.01.2020 13:37 Буравчик . Предыдущая версия .
Re: Подскажите с запросом к BigQuery (SQL)
От: RushDevion Россия  
Дата: 24.01.20 13:48
Оценка:
Если принять, что update_id увеличивается с каждым обновлением, то примерно так:
with cte as (
    select max(update_id) as last_update_id
    from history as h
    group by h.key
)
select h.update_id, h.key, h.value
from history as h
inner join cte on h.update_id = cte.last_update_id;
Re: Подскажите с запросом к BigQuery (SQL)
От: Softwarer http://softwarer.ru
Дата: 24.01.20 13:52
Оценка: -1
Здравствуйте, VmK, Вы писали:

VmK>Подскажите плиз кто знает, как должен выглядеть такой запрос? Уже всю голову сломал


В нормальном SQL похожий запрос может выглядеть примерно как

select key, max(value) keep (dense_rank last order by update_id)
from table
group by key


но гораздо правильнее он будет выглядеть так

begin
  drop эта_хрень;
  уволить_её_авторов;
  нанять_программиста;
end;
Re[2]: Подскажите с запросом к BigQuery (SQL)
От: VmK  
Дата: 24.01.20 15:31
Оценка:
Спасибо огромное! То, что нужно!!!

Б>
Б>SELECT * 
Б>FROM table
Б>WHERE id IN (
Б>  SELECT MAX(update_id)
Б>  FROM table
Б>  GROUP BY key
Б>)
Б>
Re[2]: Подскажите с запросом к BigQuery (SQL)
От: Слава  
Дата: 24.01.20 16:31
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>но гораздо правильнее он будет выглядеть так


S>
begin
S>  drop эта_хрень;
S>  уволить_её_авторов;
S>  нанять_программиста;
S>end;


А кого конкретно уволить-то? Автора темы или авторов BigQuery?
Re[3]: Подскажите с запросом к BigQuery (SQL)
От: Softwarer http://softwarer.ru
Дата: 24.01.20 17:04
Оценка:
Здравствуйте, Слава, Вы писали:

С>А кого конкретно уволить-то? Автора темы или авторов BigQuery?


К BigQuery у меня претензий нет (возможно, потому, что я с ним не работал). А вот зачем складывать данные так, чтобы для тривиального запроса требовалось завязываться узлом — вопрос, назовём так, открытый.
Re[4]: Подскажите с запросом к BigQuery (SQL)
От: vsb Казахстан  
Дата: 24.01.20 17:27
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>К BigQuery у меня претензий нет (возможно, потому, что я с ним не работал). А вот зачем складывать данные так, чтобы для тривиального запроса требовалось завязываться узлом — вопрос, назовём так, открытый.


Обычно добавляют булевский столбец типа актуальные данные или нет.
Re[4]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 24.01.20 17:44
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>К BigQuery у меня претензий нет (возможно, потому, что я с ним не работал). А вот зачем складывать данные так, чтобы для тривиального запроса требовалось завязываться узлом — вопрос, назовём так, открытый.


А как удобнее было бы складывать данные?
Best regards, Буравчик
Re[5]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 24.01.20 17:45
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Обычно добавляют булевский столбец типа актуальные данные или нет.


И при добавлении еще менять булевый столбец, зачем?
Best regards, Буравчик
Re[6]: Подскажите с запросом к BigQuery (SQL)
От: vsb Казахстан  
Дата: 24.01.20 17:48
Оценка:
Здравствуйте, Буравчик, Вы писали:

vsb>>Обычно добавляют булевский столбец типа актуальные данные или нет.


Б>И при добавлении еще менять булевый столбец, зачем?


Чтобы запросы делать не через одно место.
Re[7]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 24.01.20 18:12
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Чтобы запросы делать не через одно место.


Обычный запрос, вроде.
С индексами будет работать очень быстро.
Best regards, Буравчик
Re[8]: Подскажите с запросом к BigQuery (SQL)
От: wildwind Россия  
Дата: 25.01.20 07:29
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Обычный запрос, вроде.

Б>С индексами будет работать очень быстро.

Первые пару лет.
Re[9]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 25.01.20 10:26
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Первые пару лет.


Что произойдет через пару лет?
При каком количестве записей / объеме данных будут проблемы?
Best regards, Буравчик
Re[4]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 25.01.20 12:25
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, Слава, Вы писали:


С>>А кого конкретно уволить-то? Автора темы или авторов BigQuery?


S>К BigQuery у меня претензий нет (возможно, потому, что я с ним не работал). А вот зачем складывать данные так, чтобы для тривиального запроса требовалось завязываться узлом — вопрос, назовём так, открытый.


Ок. И так задача, хранить курсы валют и получать их на заданную дату.
Как будешь делать?

Одна таблица точно будет: период, валюта, курс.
Для ускорения, если есть потребность дергать данные ну прям очень быстро и это критично, можно сделать вторую: валюта, курс.
На первую повесить триггер и при записи/обновлении/удалении обновлять запись во второй таблица.

Так?

Теперь представь что дергать актуальные данные надо хотя и часто, в алгоритме где они нужны, время работы такого запроса меньше 1% времени. Все еще надо вторую таблицу делать?
Re[7]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 25.01.20 12:26
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, Буравчик, Вы писали:


vsb>>>Обычно добавляют булевский столбец типа актуальные данные или нет.


Б>>И при добавлении еще менять булевый столбец, зачем?


vsb>Чтобы запросы делать не через одно место.


А булевский столбец мы будем триггером обновлять по все таблице... отличный вариант.
Re[9]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 25.01.20 12:29
Оценка: +2
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, Буравчик, Вы писали:


Б>>Обычный запрос, вроде.

Б>>С индексами будет работать очень быстро.

W>Первые пару лет.


Вот смотри, ты уже вбросил данные про пару лет... При этом ты не в курсе задачи. Насколько там часто пишут данные. Насколько вообще важна история. Если там данные пишут не чаще раза в день, то оно и 100 лет будет работать отлично, всего то 300000 записей по одному свойству, да еще и индексом = 19 итераций поиска на каждое свойство.
Re[8]: Подскажите с запросом к BigQuery (SQL)
От: vsb Казахстан  
Дата: 25.01.20 15:08
Оценка:
Здравствуйте, wraithik, Вы писали:

vsb>>Здравствуйте, Буравчик, Вы писали:


vsb>>>>Обычно добавляют булевский столбец типа актуальные данные или нет.


Б>>>И при добавлении еще менять булевый столбец, зачем?


vsb>>Чтобы запросы делать не через одно место.


W>А булевский столбец мы будем триггером обновлять по все таблице... отличный вариант.


Чего? При редактировании записи проставляешь false отредактированной записи, true новой. Какой ещё триггер? Вместо одного insert получаешь insert + update. Отличий почти нет. А производительность select-ов небо и земля. Если партиционировать, то вообще разницы не будет.
Отредактировано 25.01.2020 15:08 vsb . Предыдущая версия .
Re[5]: Подскажите с запросом к BigQuery (SQL)
От: Softwarer http://softwarer.ru
Дата: 25.01.20 18:07
Оценка: 24 (1) +1
Здравствуйте, Буравчик, Вы писали:

Б>А как удобнее было бы складывать данные?


А вот за ответ на этот вопрос архитекторы и получают свои зарплаты Тут уже начинается — сколько этих данных, какие запросы к ним будут стучаться, как часто и в каких масштабах изменения, где надо вносить изменения задним числом (!) и как это всё будет меняться в ожидаемом будущем. Свою долю вносят фичи конкретной СУБД.

В целом, есть два основных варианта:

а) Основные операции идут с актуальными данными, а исторические в основном лежат. В этом случае нужен способ эффективно отделять текущие данные от прочих. В простом случае это может быть вышеупомянутый булёвый столбец. Дальше начинаются соображения о том, что актуальным данным хорошо бы лежать физически рядом и на быстых дисках, а исторические хорошо бы убрать подальше и на медленные. Поэтому могут делать отдельную таблицу актуальных данных и отдельную — исторических. Могут, например, партиционировать таблицу на "актуальную" и "историческую" части. А могут держать таблицу как историческую, а для быстрого чтения актуальных сделать materialized view.

б) Основные операции идут "на указанную дату". В этом случае естественное решение — снабжать каждую строку периодом активности, date_from / date_to. Но если данных сравнительно немного, а меняются сравнительно часто, то иногда делают слепки каждый день (чаще всего так поступают с курсами валют). Ещё один интересный вопрос: когда меняется одно поле, делать новую версию для этого поля (как в исходном примере) или для всей записи. Тратится больше места, зато быстрее выборка. Бывает, что и в этом варианте актуальные данные нужны чаще среднего — и снова начинаются приседания из предыдущего пункта.
Re[6]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 25.01.20 18:46
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>А вот за ответ на этот вопрос архитекторы и получают свои зарплаты Тут уже начинается — сколько этих данных, какие запросы к ним будут стучаться, как часто и в каких масштабах изменения, где надо вносить изменения задним числом (!) и как это всё будет меняться в ожидаемом будущем. Свою долю вносят фичи конкретной СУБД.


Архитектор должен изучить требования, а потом принимать решения.
Может это все автору совсем не надо. Автор просто спросил запрос для его данных.

S>В целом, есть два основных варианта:


Насчет архитектуры, имхо:
— надо проектировать исходя из текущих (обозримых) потребностей, а не городить суперсистему, которая способна на все
— в случае сомнения в выборе проектного решения, выбрать абстракцию и выделить выбранное решение в отдельный модуль/класс, чтобы можно было в дальнейшем легко изменить решение (например, для повышения быстродействия)
Best regards, Буравчик
Re[9]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 25.01.20 23:46
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, wraithik, Вы писали:


vsb>>>Здравствуйте, Буравчик, Вы писали:


vsb>>>>>Обычно добавляют булевский столбец типа актуальные данные или нет.


Б>>>>И при добавлении еще менять булевый столбец, зачем?


vsb>>>Чтобы запросы делать не через одно место.


W>>А булевский столбец мы будем триггером обновлять по все таблице... отличный вариант.


vsb>Чего? При редактировании записи проставляешь false отредактированной записи, true новой. Какой ещё триггер? Вместо одного insert получаешь insert + update. Отличий почти нет. А производительность select-ов небо и земля. Если партиционировать, то вообще разницы не будет.


Если инсерт в середину делаем? Или считаем только всегда в конец?
Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.
Re[10]: Подскажите с запросом к BigQuery (SQL)
От: vsb Казахстан  
Дата: 25.01.20 23:52
Оценка:
Здравствуйте, wraithik, Вы писали:

W>>>А булевский столбец мы будем триггером обновлять по все таблице... отличный вариант.


vsb>>Чего? При редактировании записи проставляешь false отредактированной записи, true новой. Какой ещё триггер? Вместо одного insert получаешь insert + update. Отличий почти нет. А производительность select-ов небо и земля. Если партиционировать, то вообще разницы не будет.


W>Если инсерт в середину делаем? Или считаем только всегда в конец?


Речь про историю изменений, что ещё за инсерт в середину. История всегда в конец дописывается.

W>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.


Ну любители писать логику на стороне сервера могут и хранимку написать, я предпочитаю писать код в приложении, а не в базе, но сути это не меняет. Кто-то забудет, получит по башке и вспомнит. А так и триггер можно отключить, а то чего он мешает базу портить (: А триггер, если есть желание, будет достаточно простой: в update проверяем, что ставится false на тот флажок; в insert проверяем, что ставится true, а у (n-1)-й записи проставлен false. Всё вытаскивается моментально.
Отредактировано 25.01.2020 23:56 vsb . Предыдущая версия . Еще …
Отредактировано 25.01.2020 23:53 vsb . Предыдущая версия .
Re[11]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 26.01.20 00:19
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Речь про историю изменений, что ещё за инсерт в середину. История всегда в конец дописывается.


Да что ты... Про изменения задним числом не слышал?

W>>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.


vsb>Ну любители писать логику на стороне сервера могут и хранимку написать, я предпочитаю писать код в приложении, а не в базе, но сути это не меняет. Кто-то забудет, получит по башке и вспомнит. А так и триггер можно отключить, а то чего он мешает базу портить (: А триггер, если есть желание, будет достаточно простой: в update проверяем, что ставится false на тот флажок; в insert проверяем, что ставится true, а у (n-1)-й записи проставлен false. Всё вытаскивается моментально.


Это пофиг где ты пишешь. Должен быть атомарный вызов чего-то, что не сломает логику.
По мне так самое верное когда есть движок, который дает бизнес-объекты, и всю логику ты пишешь на них, а не лезешь каждый раз в SQL.
Re[12]: Подскажите с запросом к BigQuery (SQL)
От: vsb Казахстан  
Дата: 26.01.20 09:03
Оценка:
Здравствуйте, wraithik, Вы писали:

vsb>>Речь про историю изменений, что ещё за инсерт в середину. История всегда в конец дописывается.


W>Да что ты... Про изменения задним числом не слышал?


Про уголовную ответственность за подделку документов слышал (: Не, поменять-то можно, структура-то позволяет. Если это надо редко. Если это надо очень часто, другой вопрос, тут уже связный список надо делать.

W>>>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.


vsb>>Ну любители писать логику на стороне сервера могут и хранимку написать, я предпочитаю писать код в приложении, а не в базе, но сути это не меняет. Кто-то забудет, получит по башке и вспомнит. А так и триггер можно отключить, а то чего он мешает базу портить (: А триггер, если есть желание, будет достаточно простой: в update проверяем, что ставится false на тот флажок; в insert проверяем, что ставится true, а у (n-1)-й записи проставлен false. Всё вытаскивается моментально.


W>Это пофиг где ты пишешь. Должен быть атомарный вызов чего-то, что не сломает логику.

W>По мне так самое верное когда есть движок, который дает бизнес-объекты, и всю логику ты пишешь на них, а не лезешь каждый раз в SQL.

Ну да, это правильно. Хотя от запросов на SQL всё равно обычно никуда не уйти, но вставка/изменение лучше всего бы в одном месте, тем более, что и всякие права проверять централизованно проще и надёжней.
Re[13]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 26.01.20 11:39
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, wraithik, Вы писали:


vsb>>>Речь про историю изменений, что ещё за инсерт в середину. История всегда в конец дописывается.


W>>Да что ты... Про изменения задним числом не слышал?


vsb>Про уголовную ответственность за подделку документов слышал (: Не, поменять-то можно, структура-то позволяет. Если это надо редко. Если это надо очень часто, другой вопрос, тут уже связный список надо делать.


ХМ... причем тут документы и база данных. Да и от ошибок никто не застрахован. Ты живешь с воем идеальном программситком мирке. Где все по инструкции.

W>>>>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.


vsb>>>Ну любители писать логику на стороне сервера могут и хранимку написать, я предпочитаю писать код в приложении, а не в базе, но сути это не меняет. Кто-то забудет, получит по башке и вспомнит. А так и триггер можно отключить, а то чего он мешает базу портить (: А триггер, если есть желание, будет достаточно простой: в update проверяем, что ставится false на тот флажок; в insert проверяем, что ставится true, а у (n-1)-й записи проставлен false. Всё вытаскивается моментально.


W>>Это пофиг где ты пишешь. Должен быть атомарный вызов чего-то, что не сломает логику.

W>>По мне так самое верное когда есть движок, который дает бизнес-объекты, и всю логику ты пишешь на них, а не лезешь каждый раз в SQL.

vsb>Ну да, это правильно. Хотя от запросов на SQL всё равно обычно никуда не уйти, но вставка/изменение лучше всего бы в одном месте, тем более, что и всякие права проверять централизованно проще и надёжней.


Уйти. Пример 1С. Мне вообще всегда фиолетово, в какой таблице на SQL что лежит.
И пример автора я бы описал так ВЫБРАТЬ * Из РегистрСведений.КурсыВалют.СрезПоследних(&Дата).
Я прекрасно понимаю во что это транслируется на SQL, но к счастью, это делает платформа, а я занимаюсь полезной деятельностью, а не рутиной.
Re[10]: Подскажите с запросом к BigQuery (SQL)
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.01.20 12:36
Оценка:
Здравствуйте, wraithik, Вы писали:

W>Если инсерт в середину делаем? Или считаем только всегда в конец?

W>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.
Стоит ещё задуматься о том, что будет, если вставка происходит в параллельных транзакциях.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Подскажите с запросом к BigQuery (SQL)
От: wraithik Россия  
Дата: 26.01.20 12:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, wraithik, Вы писали:


W>>Если инсерт в середину делаем? Или считаем только всегда в конец?

W>>Тут либо сторед-проц пишем, либо триггер делаем. Твой вариант инсерт+апдейт приведет к тому, что кто-то забудет что-то сделать.
S>Стоит ещё задуматься о том, что будет, если вставка происходит в параллельных транзакциях.

Вот теперь точно сторед-проц. Т.к. надо сперва блокировку сделать, а потом менять. Иначе будет весело, но потом, и не очень.
Re[5]: Подскажите с запросом к BigQuery (SQL)
От: varenikAA  
Дата: 27.01.20 14:08
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, Softwarer, Вы писали:


S>>К BigQuery у меня претензий нет (возможно, потому, что я с ним не работал). А вот зачем складывать данные так, чтобы для тривиального запроса требовалось завязываться узлом — вопрос, назовём так, открытый.


Б>А как удобнее было бы складывать данные?


вроде стандартное решение: две таблицы
1) основная
2) архивная
при изменении, старые значение вставляются в архив
потом, если потребуется история, можно вытянуть из архива,
в главной всегда актуальная инфа.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[6]: Подскажите с запросом к BigQuery (SQL)
От: Буравчик Россия  
Дата: 27.01.20 15:11
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>вроде стандартное решение: две таблицы

AA>1) основная
AA>2) архивная
AA>при изменении, старые значение вставляются в архив
AA>потом, если потребуется история, можно вытянуть из архива,
AA>в главной всегда актуальная инфа.

Имхо, ты решил проблему, которой у автора нет.
Усложнил систему без необходимости для этого.
Best regards, Буравчик
Re[7]: Подскажите с запросом к BigQuery (SQL)
От: varenikAA  
Дата: 28.01.20 04:13
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, varenikAA, Вы писали:


AA>>вроде стандартное решение: две таблицы

AA>>1) основная
AA>>2) архивная
AA>>при изменении, старые значение вставляются в архив
AA>>потом, если потребуется история, можно вытянуть из архива,
AA>>в главной всегда актуальная инфа.

Б>Имхо, ты решил проблему, которой у автора нет.

Б>Усложнил систему без необходимости для этого.

Спросили как хранить исторические данные.
Да, конечно, проще cte написать, проще вообще одну таблицу на все приложение.
Особенно, если учесть,что исторические данные быть может нужны лишь при просмотре единственной записи.
☭ ✊ В мире нет ничего, кроме движущейся материи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.