我在查询中有一个子选择,看起来像这样:
left outer join
(select distinct ID from OTHER_TABLE) as MYJOIN
on BASE_OBJECT.ID = MYJOIN.ID
这很简单。检查要查询的主要对象与OTHER_TABLE表示的对象之间是否存在某种关系,即MYJOIN.ID
在所讨论的行上是否为空。
但现在要求发生了一些变化。 OTHER_TABLE
中的另一行可以具有值1或0,并且查询需要知道主值与1值之间是否存在关系,以及是否存在0值。显而易见的解决方案是:
left outer join
(select distinct ID, TYPE_VALUE from OTHER_TABLE) as MYJOIN
on BASE_OBJECT.ID = MYJOIN.ID
但这样做是错误的,因为如果同一个ID存在0型和1型对象,则会增加查询返回的行数,这是不可接受的。所以我需要的是某种子选择,它将为每个不同的ID返回1行,其中“1-type exists”列和“0-type exists”列。我不知道如何在SQL中编写代码。
例如,对于下表,
ID | TYPE_VALUE
_________________
1 | 1
3 | 0
3 | 1
4 | 0
我想看到这样的结果集:
ID | HAS_TYPE_0 | HAS_TYPE_1
______________________________
1 | 0 | 1
3 | 1 | 1
4 | 1 | 0
任何人都知道如何设置查询来执行此操作?希望有最少的丑陋黑客?
答案 0 :(得分:3)
在一般情况下,您将使用EXISTS:
SELECT DISTINCT ID,
CASE WHEN EXISTS (
SELECT * FROM Table1 y
WHERE y.TYPE_VALUE = 0 AND ID = x.ID)
THEN 1
ELSE 0 END AS HAS_TYPE_0,
CASE WHEN EXISTS (
SELECT * FROM Table1 y
WHERE y.TYPE_VALUE = 1 AND ID = x.ID)
THEN 1
ELSE 0 END AS HAS_TYPE_1
FROM Table1 x;
如果表格中有非常多的元素,这将不会表现得那么好 - 那些嵌套的子选择在性能方面往往是一个死亡之吻。
对于您的具体情况,您还可以使用GROUP BY和MAX()以及MIN()来加快速度:
SELECT
ID,
CASE WHEN MIN(TYPE_VALUE) = 0 THEN '1' ELSE 0 END AS HAS_TYPE_0,
CASE WHEN MAX(TYPE_VALUE) = 1 THEN '1' ELSE 0 END AS HAS_TYPE_1
FROM Table1
GROUP BY ID;
答案 1 :(得分:2)
而不是select distinct ID, TYPE_VALUE from OTHER_TABLE
使用
select ID,
MAX(CASE WHEN TYPE_VALUE =0 THEN 1 END) as has_type_0,
MAX(CASE WHEN TYPE_VALUE =1 THEN 1 END) as has_type_1
from OTHER_TABLE
GROUP BY ID;
您可以使用PIVOT
opearator ...