【问题标题】:A better way to return '1' if a left join returns any rows?如果左连接返回任何行,返回“1”的更好方法?
【发布时间】:2011-03-12 21:16:39
【问题描述】:

我有三个表,“A”、“B”和“C”。我有关于“A”和“B”的查询,但我想添加一个字段,告诉我是否有一个或多个(我不关心有多少)“C”外键为“A”。

这是我所拥有的:

SELECT    A.A_id, A.col_2, col_3, B.col_2, A.col_4
          count(C.id) as C_count
FROM      A
JOIN      B ON (A.B_id = B.B_id)
LEFT JOIN C ON (A.A_id = C.A_id)
WHERE     A.A_id = ?
GROUP BY  A.A_id, A.col_2, col_3, B.col_2, A.col_4
ORDER BY  CASE WHEN A.col_2 = ?
               THEN 0
               ELSE 1 
          END, col_3;

这似乎有点低效,既因为我必须在GROUP BY 中列出所有这些字段,也因为我正在计算我真正想要的是是否至少有一个匹配项。这可以改进吗?

【问题讨论】:

  • 仅仅因为您必须输入很多列名并不会使查询效率低下;)但是在这种情况下,您是正确的。对计数进行排序和制表成本很高,但也许更昂贵的是数据库必须遍历表 C 中的所有行才能获得该计数。使用 EXISTS 解决方案,一旦找到第一个匹配行,它就可以停止查找。

标签: sql oracle join


【解决方案1】:

将 Exists 与子查询一起使用...

 Select A.A_id, A.col_2, col_3, 
    B.col_2, A.col_4, 
    Case When Exists (Select * From C
                      Where A_id = A.A_id)
         Then 1 Else 0 End As C_Exists
 From A Join B 
     On (A.B_id = B.B_id) 
 Where A.A_id = ?    
 Order By Case When A.col_2 = ? 
           Then 0 Else 1 End, col_3;

【讨论】:

  • 优秀。解释计划说它也更好。 3分钟后我可以接受。
  • @Paul Tomblin:这是因为只要找到第一个成功匹配条件的 EXISTS 就会返回 true - EXISTS 不需要检查所有匹配条件。
猜你喜欢
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多