Как объединить несколько запросов выбора из одной таблицы

Я хотел бы запросить таблицу с несколькими столбцами (например, 4 ниже), из которой я хотел бы создать таблицу моментальных снимков, которая может предоставлять информацию о количестве атрибутов каждый день.

ID пользователя атрибут1 атрибут2 атрибут3 1 истинный Привет Собака 2 ЛОЖЬ Привет 3 Привет 4 ЛОЖЬ Кот 5 истинный Привет Собака 6 ЛОЖЬ Кот 7 Привет 8 ЛОЖЬ Собака 9 Кот 10 ЛОЖЬ Привет Кот

Например, сверху

пользовательидкаунт имя_атрибута ДатаКогдаСнимокВставлен 7 атрибут1 16 апреля 2024 г. 6 атрибут2 16 апреля 2024 г. 7 атрибут3 16 апреля 2024 г.

В этом случае у нас могут быть миллионы строк в исходной таблице с более чем 100 столбцами, и мы хотели бы каждый день заполнять таблицу моментальных снимков количеством пользователей с ненулевыми значениями для каждого атрибута и датой создания этого моментального снимка.

Я формулирую свой запрос следующим образом: -

select COUNT(DISTINCT userId) as userIdCount from orig_table where
    attr1 IS NOT NULL UNION Select COUNT(DISTINCT userId) as userIdCount
    from orig_table where attr2 IS NOT NULL UNION Select COUNT(DISTINCT
    userId) as userIdCount from orig_table where attr3 IS NOT NULL;

Есть ли оптимизированный способ написать несколько запросов на выборку вместе. Я начал с создания множественного запроса на выборку и вставки его в выходную таблицу один за другим, но это кажется плохим шаблоном. Пожалуйста, предложите, как этого добиться, чтобы это можно было масштабировать.

PS: Новичок (который впервые изучает запросы к БД)

попробуйте использовать представления.

Abhishek Kumar 16.04.2024 09:39

Спасибо, Абхишек! Любое предложение о том, как объединить несколько вариантов выбора для создания представлений.

TechDan 16.04.2024 09:47

Я думаю, вы имеете в виду материализованный взгляд . Обычный view пересчитывает запрос для каждого select из него, тогда как materialized view сохраняет снимок результата до тех пор, пока вы не обновите его. Часть проблемы с множественным выбором можно решить с помощью динамического SQL в блоке PL/pgSQL.

Zegarek 16.04.2024 09:51

Удалены конфликтующие теги товаров. Пожалуйста, добавьте обратно тот, который вы действительно используете!

Shadow 16.04.2024 11:11
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
4
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы имеете в виду материализованный взгляд . Обычный view пересчитывает запрос для каждого select из него, тогда как materialized view сохраняет снимок результата до тех пор, пока вы не обновите его.

Часть проблемы с множественным выбором можно решить с помощью динамического SQL в блоке PL/pgSQL.

Демо на db<>fiddle:

do $f$
declare column_name_ text;
        dynamic_sql_query text;
        dynamic_sql_query_per_table text:=$$SELECT COUNT(DISTINCT "userId") AS %1$I
                                                 ,'%2$I' as "attrName"
                                                 ,now() AS "dateWhenSnapshotInserted"
                                           FROM orig_table 
                                           WHERE %2$I IS NOT NULL$$;
begin
for column_name_ in select column_name 
                    from information_schema.columns
                    where table_name='orig_table'
loop
    dynamic_sql_query:=concat_ws(' UNION ALL '
                                 ,dynamic_sql_query
                                 ,format( dynamic_sql_query_per_table
                                         ,column_name_||'Count'
                                         ,column_name_));
end loop;
execute format('CREATE MATERIALIZED VIEW orig_table_counts AS %s',dynamic_sql_query);
end $f$;

select * from orig_table_counts;
пользовательидкаунт имя_атрибута ДатаКогдаСнимокВставлен 10 "ID пользователя" 2024-04-16 09:07:44.604273+00 7 атрибут1 2024-04-16 09:07:44.604273+00 6 атрибут2 2024-04-16 09:07:44.604273+00 7 атрибут3 2024-04-16 09:07:44.604273+00
  1. concat_ws() заботится о том, чтобы поставить union all между каждым запросом, который собирает значения для каждого столбца. Он пропускает null аргументы, поэтому изначально объявленный, но незаполненный dynamic_sql_query предотвращает использование ведущего/конечного union разделителя.
  2. $$ — это кавычки, которые позволяют использовать внутри них другие типы кавычек. %1$I и %2$I являются заполнителями format(), указывающими ему вставить 1-й/2-й аргумент в качестве необязательного идентификатора I в двойных кавычках. %s сообщает ему, чтобы он поместил еще одну строку в виде простой строки без какой-либо специальной обработки.
  3. Обязательно обратите внимание на чувствительность вашего идентификатора к регистру: если вы не используете двойные кавычки ", все они сворачиваются в нижний регистр, а это означает, что userId на самом деле может называться userid.

Другие вопросы по теме