多列子查询
Subquery with multiple columns
我的数据库中有一个设计不佳的 table,其中包含一些我需要提取的信息。假设我有以下查询:
SELECT
(SELECT I FROM X WHERE X.A = FOO AND X.B = KEY),
(SELECT J FROM X WHERE X.A = BAR AND X.B = KEY),
(SELECT K FROM X WHERE X.A = BAZ AND X.B = KEY)
我需要将查询扩展到 select 其他一些字段。我的第一个想法是:
SELECT
(SELECT I FROM X WHERE X.A = FOO AND X.B = KEY),
(SELECT J FROM X WHERE X.A = BAR AND X.B = KEY),
(SELECT K FROM X WHERE X.A = BAZ AND X.B = KEY)
(SELECT L, M, N FROM X WHERE X.A = QUX AND X.B = KEY)
但是,我收到一条错误消息,指出获取列的子查询只能获取一列,除非它是通过 EXISTS 子句引入的。我可以这样写最后一个子查询:
(SELECT L, M, N FROM X AS OUTER
WHERE EXISTS
(SELECT ID FROM X WHERE X.A = QUX AND X.B = KEY AND X.ID = OUTER.ID)(
这个解决方案不会不必要地很重吗?还有其他解决方案吗?
编辑:
我需要将信息提取到一行中。我还应该提到,不能保证每个 X.A 都存在(可能有些键只有 FOO,其他键有 BAR 和 QUX,等等),所以加入是不可能的。
编辑:@Saharsh Shah 请求了一些示例数据:
|X.B |X.A|X.I |X.J |X.K |X.L |X.M |X.N |
|KEY1|FOO|ICONTENT| | | | | |
|KEY1|栏| |J内容| | | | |
|KEY1|BAZ| | |K内容| | | |
|KEY1|QUX| | | |L内容|M内容|N内容|
|KEY2|栏| |J内容| | | | |
|KEY3|FOO|ICONTENT| | | | | |
|KEY3|QUX| | | |L内容|M内容|N内容|
以及预期的结果:
对于密钥 1:
X.I |X.J |X.K |X.L |X.M |X.N |
ICONTENT|JCONTENT|KCONTENT|LCONTENT|MCONTENT|NCONTENT|
对于密钥 2:
X.I |X.J |X.K |X.L |X.M |X.N |
|J内容| | | | |
对于密钥 3:
X.I |X.J |X.K |X.L |X.M |X.N |
图标内容| | |L内容|M内容|N内容|
这可以通过两种方式完成:-
select i, j , k , l , m, n
from x
where i in (select i from x where x.a = 'FOO' or x.B = 'KEY') and
j in (select j from x where x.b = 'BAR' or x.B = 'KEY') and
k in (select k from x where x.c = 'BAZ' or x.B = 'KEY')
或者另一种方式是:
select (select count(i) from x where x.a = 'foo') as i , (select count(j) from x where x.b in ('KEY', 'BAR') as j , (select count(k) from x where x.c = 'BAZ' and x.B = 'KEY') as k , l, m , n
from x
使用CASE语句来验证条件
试试这个:
SELECT X.B,
MAX(CASE WHEN X.A = FOO THEN I ELSE '' END) AS I,
MAX(CASE WHEN X.A = BAR THEN J ELSE '' END) AS J,
MAX(CASE WHEN X.A = BAZ THEN K ELSE '' END) AS K,
MAX(CASE WHEN X.A = QUX THEN L ELSE '' END) AS L,
MAX(CASE WHEN X.A = QUX THEN M ELSE '' END) AS M,
MAX(CASE WHEN X.A = QUX THEN N ELSE '' END) AS N
FROM X
WHERE X.B = KEY
GROUP BY X.B;
你可以使用派生的 table 作为这个
Select foo.I, bar.J , baz.K, qux.L, qux.M ,qux.N from x
left outer join (Select * from x where x.A = foo) foo on foo.b = x.b
left outer join (Select * from x where x.A = bar) bar on bar.b = x.b
left outer join (Select * from x where x.A = baz) baz on baz.b = x.b
left outer join (Select * from x where x.A = qux) qux on qux.b = x.b
where x.B = key
如果您确定带有 a=foo , ... 的数据存在,内连接也适用
我的数据库中有一个设计不佳的 table,其中包含一些我需要提取的信息。假设我有以下查询:
SELECT
(SELECT I FROM X WHERE X.A = FOO AND X.B = KEY),
(SELECT J FROM X WHERE X.A = BAR AND X.B = KEY),
(SELECT K FROM X WHERE X.A = BAZ AND X.B = KEY)
我需要将查询扩展到 select 其他一些字段。我的第一个想法是:
SELECT
(SELECT I FROM X WHERE X.A = FOO AND X.B = KEY),
(SELECT J FROM X WHERE X.A = BAR AND X.B = KEY),
(SELECT K FROM X WHERE X.A = BAZ AND X.B = KEY)
(SELECT L, M, N FROM X WHERE X.A = QUX AND X.B = KEY)
但是,我收到一条错误消息,指出获取列的子查询只能获取一列,除非它是通过 EXISTS 子句引入的。我可以这样写最后一个子查询:
(SELECT L, M, N FROM X AS OUTER
WHERE EXISTS
(SELECT ID FROM X WHERE X.A = QUX AND X.B = KEY AND X.ID = OUTER.ID)(
这个解决方案不会不必要地很重吗?还有其他解决方案吗?
编辑:
我需要将信息提取到一行中。我还应该提到,不能保证每个 X.A 都存在(可能有些键只有 FOO,其他键有 BAR 和 QUX,等等),所以加入是不可能的。
编辑:@Saharsh Shah 请求了一些示例数据:
|X.B |X.A|X.I |X.J |X.K |X.L |X.M |X.N | |KEY1|FOO|ICONTENT| | | | | | |KEY1|栏| |J内容| | | | | |KEY1|BAZ| | |K内容| | | | |KEY1|QUX| | | |L内容|M内容|N内容| |KEY2|栏| |J内容| | | | | |KEY3|FOO|ICONTENT| | | | | | |KEY3|QUX| | | |L内容|M内容|N内容|
以及预期的结果: 对于密钥 1:
X.I |X.J |X.K |X.L |X.M |X.N | ICONTENT|JCONTENT|KCONTENT|LCONTENT|MCONTENT|NCONTENT|
对于密钥 2:
X.I |X.J |X.K |X.L |X.M |X.N | |J内容| | | | |
对于密钥 3:
X.I |X.J |X.K |X.L |X.M |X.N | 图标内容| | |L内容|M内容|N内容|
这可以通过两种方式完成:-
select i, j , k , l , m, n
from x
where i in (select i from x where x.a = 'FOO' or x.B = 'KEY') and
j in (select j from x where x.b = 'BAR' or x.B = 'KEY') and
k in (select k from x where x.c = 'BAZ' or x.B = 'KEY')
或者另一种方式是:
select (select count(i) from x where x.a = 'foo') as i , (select count(j) from x where x.b in ('KEY', 'BAR') as j , (select count(k) from x where x.c = 'BAZ' and x.B = 'KEY') as k , l, m , n
from x
使用CASE语句来验证条件
试试这个:
SELECT X.B,
MAX(CASE WHEN X.A = FOO THEN I ELSE '' END) AS I,
MAX(CASE WHEN X.A = BAR THEN J ELSE '' END) AS J,
MAX(CASE WHEN X.A = BAZ THEN K ELSE '' END) AS K,
MAX(CASE WHEN X.A = QUX THEN L ELSE '' END) AS L,
MAX(CASE WHEN X.A = QUX THEN M ELSE '' END) AS M,
MAX(CASE WHEN X.A = QUX THEN N ELSE '' END) AS N
FROM X
WHERE X.B = KEY
GROUP BY X.B;
你可以使用派生的 table 作为这个
Select foo.I, bar.J , baz.K, qux.L, qux.M ,qux.N from x
left outer join (Select * from x where x.A = foo) foo on foo.b = x.b
left outer join (Select * from x where x.A = bar) bar on bar.b = x.b
left outer join (Select * from x where x.A = baz) baz on baz.b = x.b
left outer join (Select * from x where x.A = qux) qux on qux.b = x.b
where x.B = key
如果您确定带有 a=foo , ... 的数据存在,内连接也适用