Oracle Count,即使没有任何东西

时间:2011-11-27 22:27:06

标签: sql oracle count

所以我有这个问题:

SELECT p.*, d.reviews, TRUNC(ds.ratingAvg, 2) as ratingAvg
  FROM place p, 
    (SELECT pid,
      COUNT(rating) as ratings, 
      COUNT(review) as reviews
      FROM describes 
      GROUP BY pid) d,
    (SELECT pid, AVG(rating) as ratingAvg FROM describes GROUP BY pid) ds
  WHERE d.pid = p.pid AND d.pid = ds.pid
;

它将从地方返回东西,然后d是另一个表描述。它将获得该地点的评论数量和平均评分。只要描述表中有某些内容,这就完美无缺。我怎样才能获得没有任何内容的东西。基本上是0评级或0评论。

由于

2 个答案:

答案 0 :(得分:2)

使用coalesce()和LEFT JOIN,如下所示:

SELECT p.*
      ,COALESCE(d.reviews, 0)    AS reviews
      ,COALESCE(ds.ratingAvg, 0) AS ratingAvg
  FROM place p 
  LEFT JOIN (
       SELECT pid
  --         ,COUNT(rating) AS ratings -- unused?
             ,COUNT(review) AS reviews
       FROM   describes 
       GROUP  BY pid) d ON d.pid = p.pid
  LEFT JOIN (
       SELECT pid
             ,TRUNC(AVG(rating), 2) AS ratingAvg
       FROM   describes
       GROUP  BY pid) ds ON ds.pid = p.pid;

注意我如何在第二个JOIN中使用ON ds.pid = p.pid,而不是像ON ds.pid = d.pid那样使用SELECT p.* ,COALESCE(d.reviews, 0) AS reviews ,COALESCE(d.ratingAvg, 0) AS ratingAvg FROM place p LEFT JOIN ( SELECT pid -- ,COUNT(rating) AS ratings -- unused? ,COUNT(review) AS reviews ,TRUNC(AVG(rating), 2) AS ratingAvg FROM describes GROUP BY pid) d ON d.pid = p.pid;

如果第三个关系保持连接到第二个关系,而第二个关系又连接到第一个关系,则如果在第二个关系中找不到任何行,则会丢失第三个关系中的行。如果可能,左连接应该是第一个关系。在这种特殊情况下没有任何区别,因为我们在同一个表上有两个无条件查询 - 应该简化:

{{1}}

答案 1 :(得分:2)

通过合并INNER JOIN子句中的结果而不是隐式WHERE,您应该使用LEFT JOINS

使用显式JOIN

SELECT  p.*
        , d.reviews
        , TRUNC(ds.ratingAvg, 2) as ratingAvg
FROM    place p
        LEFT JOIN (
          SELECT  pid
                  , COUNT(rating) as ratings
                  , COUNT(review) as reviews
          FROM    describes 
          GROUP BY 
                  pid
        ) d ON d.pid = p.pid
        LEFT JOIN (
          SELECT  pid
                  , AVG(rating) as ratingAvg 
          FROM    describes 
          GROUP BY 
                  pid
        ) ds ON ds.pid = d.pid

LEFT OUTER JOIN

  

表A和表的左外连接(或简称左连接)的结果   B总是包含“左”表(A)的所有记录,即使是   join-condition在“右”表中找不到任何匹配的记录   (B)。这意味着如果ON子句匹配B中的0(零)记录,   连接仍会在结果中返回一行 - 但每个中都有NULL   B栏。