SQL-запрос для ключа и значения - PullRequest
0 голосов
/ 12 марта 2019

Мне нужно написать запрос, который делает следующее. После поиска на различных форумах я вижу, что «PIVOT» является одним из способов реализации этого. Я все еще пытаюсь написать запрос, используя PIVOT, но тем временем кто-нибудь может подсказать, есть ли другой альтернативный способ сделать то же самое?

TABLE T1

s_ID | a_ID
------------
 1   |  a1
------------
 2   |  a2
------------

 TABLE T2
a_ID | Key | Value
a1   | k1  | v1
a1   | k2  | v2
a1   | k3  | v3
a2   | k1  | v1
a2   | k2  | v2
a2   | k4  | v4

Ожидается ВЫХОД из запроса:

s_ID | a_ID | k1 | k2 | k3 | k4
---------------------------------
 1   | a1   | v1 | v2 | v3 |
---------------------------------
 2   | a2   | v1 | v2 |    | v4 

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Это альтернативное решение, но оно может быть полезно для вас или кого-то еще.

Вам необходимо PIVOT динамических данных, но в настоящее время Oracle не может сделать это в одном запросе SQL, только для статическихключи.Итак, давайте назначим статические ключи для ваших динамических ключей.

with

-- your key/value data table
tmp_data(fk_id, key_name, key_value) as 
(
  select 1, 'a', '000' from dual union 
  select 1, 'b', '111' from dual union 

  select 2, 'a', '222' from dual union 
  select 2, 'c', '333' from dual union 

  select 3, 'a', '444' from dual union 

  select 4, 'c', '555' from dual union 
  select 4, 'd', '666' from dual 
),

-- a map of static keys for your dynamic keys
tmp_static(fk_id, key_name, key_num) as 
(
  select 
    0, -- just to union the data later
    key_name, -- your dynamic key
    row_number() over(order by key_name) -- our static key
  from tmp_data 
  group by key_name
)

-- here we get a header row
select *
from tmp_static
pivot
(
  max(key_name)
  for(key_num) in (1,2,3,4,5,6,7,8,9,10,11,12) -- static keys expected at most
)

union 

-- here we get data rows
select *
from
(
  select 
    t1.fk_id,
    t1.key_value,
    t2.key_num
  from tmp_data t1
  inner join tmp_static t2 on 1=1
    and t2.key_name = t1.key_name
)
pivot
(
  max(key_value)
  for(key_num) in (1,2,3,4,5,6,7,8,9,10,11,12) -- static keys expected at most
)
;

Результат будет следующим:

result

Как вы можете видетьв результате и в SQL первая строка фактически содержит имя ваших динамических ключей, потому что мы не могли отобразить их в PIVOT до этого.Другие строки - ваши данные.

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

Как вы можете видеть из моего запроса, я предположил, что максимальное количество ключей для одного и того же fk_id равно 12, но вы всегда можете быть уверены в том, сколько столбцов имеют данные, выглядящие в строке заголовка, сколько столбцов имеетимена.Ваши приложения должны правильно обрабатывать эту строку заголовка и эти пустые столбцы.

Надеюсь, это поможет.

0 голосов
/ 12 марта 2019

использовать условное агрегирование

select s_id,t1.a_id, max(case when key='k1' then value end),
max(case when key='k1' then value end),
max(case when key='k2' then value end),
max(case when key='k3' then value end) from table1 t1 join table2 t2 on t1.a_ID=t2.a_ID
 group by s_id,t1.a_id
...