6

我有一个查询连接了几个表并返回了很多列。

另一个表的索引列引用这些连接表之一的 PK。现在我想在查询中添加另一列,说明新表中是否存在至少一个具有该 ID 的行。

所以如果我有一张旧桌子

ID
 1
 2
 3

和新表

REF_ID
1
1
1
3

那么我想得到

ID   REF_EXISTS
 1            1
 2            0
 3            1

我可以想到几种方法来做到这一点,但最优雅/最有效的方法是什么?


编辑 我测试了旧表中提供 50.000 条记录的查询的性能,每隔一条记录与新表中的两行匹配,因此一半的记录有 REF_EXISTS=1。

如果有人感兴趣,我会添加平均结果作为答案的评论。谢谢大家!

4

4 回答 4

8

另外一个选项:

select O.ID
    , case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
   on O.id = N.ref_id
于 2009-12-16T20:24:56.147 回答
4

我会:

select distinct ID,
       case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
    then 1 else 0 end
    from ID_TABLE

如果您在 PK 和 FK 上有索引,您将摆脱表扫描和索引查找。

问候 K

于 2009-12-17T12:50:10.400 回答
2

采用:

   SELECT DISTINCT t1.id,
          CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
     FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id

添加DISTINCT以确保仅显示唯一的行。

于 2009-12-16T19:38:22.310 回答
1

Ajoin可以为一个 id 返回多行,就像id=1在示例数据中所做的那样。您可以通过以下方式将其限制为每个 ID 一行:

SELECT 
    t1.id
,   COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id

确保每个group byid 只有一行。如果count(distinct t2.ref_id)找到一行,则为 1,否则为 0。

编辑:你可以在没有 的情况下重写它group by,但我怀疑这会让事情变得更容易:

SELECT 
    t1.id
,   CASE WHEN EXISTS (
        SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
        THEN 1 ELSE 0 END as REF_EXISTS
,   ....
FROM TABLE_1 t1
于 2009-12-16T19:42:10.970 回答