SQL-запрос для группировки таблицы в таблицу таблиц?

#sql #string #group-by #powerbi #pivot

#sql #строка #группировать по #powerbi #сводный

Вопрос:

Я нахожусь в процессе «перевода» запросов Power BI в запросы SQL. Один из ключевых запросов выполняет следующее:

  1. Принимает следующую таблицу:
  ----- ----- ---------- 
| PID | FID | Quantity |
 ----- ----- ---------- 
| 1   | A   | 15       |
 ----- ----- ---------- 
| 1   | B   | 2        |
 ----- ----- ---------- 
| 2   | B   | 3        |
 ----- ----- ---------- 
| 2   | D   | 8        |
 ----- ----- ---------- 
| 3   | C   | 2        |
 ----- ----- ---------- 
  
  1. Сгруппировать по PID, сохранив все строки (каждая Data представляет собой таблицу):
  ----- ------- 
| PID | Table |
 ----- ------- 
| 1   | Data  |
 ----- ------- 
| 2   | Data  |
 ----- ------- 
| 3   | Data  |
 ----- ------- 
  
  1. Выполняет некоторую пользовательскую логику / манипуляции (некоторые из которых очень сложные, поэтому не просто COUNT или MAX и т.д.) Для каждого Data и превращает каждую Data в новую таблицу для каждой строки:
  ----- ------- ------------- 
| PID | Table | Transformed |
 ----- ------- ------------- 
| 1   | Data  | Data        |
 ----- ------- ------------- 
| 2   | Data  | Data        |
 ----- ------- ------------- 
| 3   | Data  | Data        |
 ----- ------- ------------- 
  
  1. Разверните Transformed столбец:
  ----- ---------------- ---------------- 
| PID | ResultColumn-1 | ResultColumn-2 |
 ----- ---------------- ---------------- 
| 1   | SomeResult-1   | SomeResult-1b  |
 ----- ---------------- ---------------- 
| 2   | SomeResult-2   | SomeResult-2b  |
 ----- ---------------- ---------------- 
| 3   | SomeResult-3   | SomeResult-3b  |
 ----- ---------------- ---------------- 
  

Можно ли выполнить эту процедуру в SQL? Я думал, что мы могли бы использовать Group By с какой-нибудь пользовательской функцией, но не совсем уверен, как это сделать — любые рекомендации были бы очень признательны.

Спасибо!


Пример вывода:

  ----- ------------------ ---------------- 
| PID | ResultColumn-1   | ResultColumn-2 |
 ----- ------------------ ---------------- 
| 1   | There are 2 of B | and 15 of A    |
 ----- ------------------ ---------------- 
| 2   | There are 8 of D | and 3 of B     |
 ----- ------------------ ---------------- 
| 3   | There are 2 of C |                |
 ----- ------------------ ---------------- 
  

Комментарии:

1. » все данные являются таблицей » — это не имеет смысла. «Таблица» не может содержаться в результате запроса. То, как вы представили данные, указывает на то, что «данные» на самом деле являются значением столбца , а не «таблицей». Ваш выбор формулировки делает это очень трудным для понимания. Не могли бы вы, пожалуйста, создать реальный пример, используя инструкции create table and insert into ?

2. Спасибо @a_horse_with_no_name, я объяснял это в контексте того, что делал PowerQuery. В Power Query «значением столбца» может быть таблица. Перевод этой функциональности на SQL — это то, с чем я борюсь.

Ответ №1:

Вы можете сделать это с помощью row_number() и условной агрегации:

 select 
    pid,
    max(case when rn = 1 then concat('There are ', quantity, ' of ', fid) end) res1,
    max(case when rn = 2 then concat('And ', quantity, ' of ', fid) end) res2
from (
    select 
        t.*,
        row_number() over(partition by pid order by fid desc) rn
    from mytable t
) t
group by pid
  

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

Комментарии:

1. Интересно — я никогда не понимал PARTITION BY . Как бы ваш запрос обрабатывал случай, когда на pid приходится только 1 строка?

2. @Schteeb: если имеется только одна строка, это генерирует результат, который вы показали для pid 3. Вы можете выполнить подзапрос независимо, чтобы увидеть результат, который он выдает, и лучше понять запрос.

Ответ №2:

Да, это возможно с помощью JOIN объединения между ними, а затем вы можете сгруппировать свои результаты или выполнить дальнейшую обработку над ними.

Ваш первоначальный запрос был бы чем-то вроде :

 SELECT 
    PID 
,   Table 
,   Transformed 
,   ResultColumn-1
,   ResultColumn-2
FROM 
    table1 t1
LEFT JOIN table2 t2 ON t2.PID = t1.PID 
LEFT JOIN table3 t3 ON t3.PID = t1.PID 
LEFT JOIN table4 t4 ON t4.PID = t1.PID 
  

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

Если вы предоставили ожидаемые результаты, то мы можем предоставить вам начальный запрос, который их выдаст, который вы можете использовать в качестве запуска!

Комментарии:

1. Спасибо за это! Что такое table1, table2 и т.д. в вашем примере? Я также добавил несколько примеров вывода. По сути, измените сгруппированные результаты на противоположные и добавьте немного текста вокруг них.

2. @Schteeb таблицы1 .. 4 — это просто примеры того, что вы уже предоставили. (например, Таблица1 — это первый пример PID, FID, количества). Пример вывода несколько нуждается в уточнении, как определить, в каком ResultColumn-x из них находится FID under? в вашем примере ясно, как вы этого хотите, но бизнес-логика, лежащая в основе группировки результатов, неясна.