假设我有下表(id_a,id_b,类型实际上是整数,数据实际上是xml):
id_a id_b type data
-----+------+--------+--------
1 1 X X1
1 1 Y Y1
7 17 Y Y2
7 99 X X2
9 20 Z Z1
id_a,id_b和type的组合是唯一的。 现在,我编写的程序将输入一个我关心的类型列表作为输入。假设此列表包含X和Y.现在我想做一些最终得到以下结果的SQL-Magic:
id_a id_b X Y
-----+------+--------+--------
1 1 X1 Y1
7 17 NULL Y2
7 99 X2 NULL
单词:我想要一行包含id_a和id_b的所有数据,列出数据列。
我能够自己找到一个查询,最终得到下表:
table:
id_a id_b data_x data_y
-----+------+--------+--------
1 1 X1 NULL
1 1 NULL Y1
7 17 NULL Y2
7 99 X2 NULL
查询:
select
id_a,
id_b,
case when type = 'X' then data
end data_x,
case when type = 'Y' then data
end data_y,
from
mytable
order by
id_a,id_b
在此表中保证
where data_x is not null or data_y is not null
轻松过滤)如果我现在可以做select coalesce(case ... data_y),coalesce(case ... data_y) from ... group by id_a,id_b
那么我相信我会成为我想去的地方,但不幸的是,coalesce不是一个聚合函数,而是一个标量函数。
在我的客户端应用程序(用Java编写)中,我当然可以迭代行,合并行,但这看起来不是很优雅;-)。是否有“漂亮”的方法来解决这个问题?
我使用的是DB2 V9.7,但我更喜欢便携式解决方案......
答案 0 :(得分:2)
使用MAX?
SELECT
id_a,
id_b,
MAX(CASE WHEN type = 'X' THEN data END) AS data_x,
MAX(CASE WHEN type = 'Y' THEN data END) AS data_y
FROM
myTable
GROUP BY
id_a,
id_b
修改强>
如果你不能使用聚合函数,这样的东西是否适合你的需要?
SELECT
map.id_a,
map.id_b,
myTableX.data AS data_x,
myTableY.data AS data_y
FROM
(SELECT id_a, id_b FROM myTable GROUP BY id_a, id_b) AS map
LEFT JOIN
myTable AS myTableX
ON myTalbeX.id_a = map.id_a
AND myTableX.id_b = map.id_b
AND myTableX.type = 'X'
LEFT JOIN
myTable AS myTableY
ON myTalbeY.id_a = map.id_a
AND myTableY.id_b = map.id_b
AND myTableY.type = 'Y'
答案 1 :(得分:1)
这会得到您想要的结果:
create table myTable (
id_a int not null,
id_b int not null,
type char(1) not null,
data varchar(10),
unique (id_a, id_b, type)
);
insert into myTable values (1, 1, 'X', 'X1');
insert into myTable values (1, 1, 'Y', 'Y1');
insert into myTable values (7, 17, 'Y', 'Y2');
insert into myTable values (7, 99, 'X', 'X2');
insert into myTable values (9, 20, 'Z', 'Z1');
select coalesce(X.id_a, Y.id_a) as id_a, coalesce(X.id_b, Y.id_b) as id_b,
X.data as X, Y.data as Y
from (select * from myTable where type = 'X') X
full outer join (select * from myTable Y where type = 'Y') Y
on X.id_a = Y.id_a and X.id_b = Y.id_b
结果
ID_A ID_B X Y
---- ---- ---- ----
1 1 X1 Y1
7 17 NULL Y2
7 99 X2 NULL
答案 2 :(得分:0)
您仍需要做一些事情,将出现在不同记录中的数据放入结果集的同一记录中。为此,您需要使用聚合函数,例如最大,最小我无权访问DB2,但在许多方面它与Oracle非常相似。以下在Oracle上运行得很好。
with tmp as
(select 1 id_a, 1 id_b, 'X' type_, 'X1' data_ from dual union
select 1 id_a, 1 id_b, 'Y' type_, 'Y1' data_ from dual union
select 7 id_a, 17 id_b, 'Y' type_, 'Y2' data_ from dual union
select 7 id_a, 99 id_b, 'X' type_, 'X2' data_ from dual union
select 9 id_a, 20 id_b, 'Z' type_, 'Z1' data_ from dual)
select distinct
id_a,
id_b,
max(decode(type_, 'X', data_, null)) data_x,
max(decode(type_, 'Y', data_, null)) data_y
from tmp
group by id_a, id_b
修改强> 对于非聚合版本,您可以使用:
with tmp as
(select 1 id_a, 1 id_b, 'X' type_, 'X1' data_ from dual union
select 1 id_a, 1 id_b, 'Y' type_, 'Y1' data_ from dual union
select 7 id_a, 17 id_b, 'Y' type_, 'Y2' data_ from dual union
select 7 id_a, 99 id_b, 'X' type_, 'X2' data_ from dual union
select 9 id_a, 20 id_b, 'Z' type_, 'Z1' data_ from dual)
select nvl(x.id_a, y.id_a) id_a, nvl(x.id_b, y.id_b) id_b, x.data_, y.data_
from tmp x
full outer join tmp y
on ( x.id_a = y.id_a
and x.id_b = y.id_b
and x.type_ = 'X'
and y.type_ = 'Y')
where x.data_ like 'X%' or y.data_ like 'Y%'