【问题标题】:mysql join return 0 for one column with other columns intactmysql join 为一列返回 0,其他列保持不变
【发布时间】:2014-10-03 05:16:22
【问题描述】:

我希望加入多个表,例如-Categoriesmenusrestaurantsreviews 等。 以返回提供插入食物的餐厅的价格。 除了reviews 表中的numberOfReviews 之外,一切正常。

如果餐厅没有评论,则 0 列的输出应为 0,但应检索其他列值,即价格、名称等。

通过以下查询,我得到所有字段为nullcount(numReviews)0

 select r.id
     ,r.`Name`
     ,r.`Address`
     ,r.city
     ,r.`Rating`
     ,r.`Latitude`
     ,a.`AreaName`
     ,m.`Price`
     ,count(rv.id)
 from `categories` c, `menus` m, `restaurants` r, areas a, reviews rv
 where m.`ItemName`="tiramisu"
     and c.`restaurant_id`=r.`id`
     and m.`category_id`=c.id
     and r.`AreaId`=a.`AreaId`

如果我不能在where 子句中匹配rv.restaurant_id=r.id(显然)。

我哪里错了?我该如何解决?

已编辑

    select  r.id, 
 r.`Name`,
 r.`Address`,
 r.city,
 r.`Rating`,
 r.`Latitude`,
 a.`AreaName`, 
 m.`Price`, 
 r.`Longitude`, 
 r.Veg_NonVeg,
 count(rv.id)
 from restaurants r LEFT JOIN `reviews` rv on rv.`restaurant_id`=r.`id`
inner join `categories` c on c.`restaurant_id` = r.id
inner join `menus` m on m.`category_id` = c.id
inner join `areas` a on a.`AreaId` = r.`AreaId`
 where m.`ItemName`="tiramisu"

【问题讨论】:

  • 如果您想在reviews 表中没有匹配项时返回任何内容,则需要使用LEFT JOIN
  • @Barmar - 谢谢我试过这个,但现在我写计数(rv.id)时只得到一行。查看我编辑的问题
  • count(numReviews)count(rv.id) 相同?
  • 你在找COALESCE
  • @z22 如果您在使用 COUNT() 之类的聚合函数时想要多行,则需要使用 GROUP BY 来获取每个 ID 的单独计数。否则,它将所有内容合并为一个大数。

标签: php mysql sql join


【解决方案1】:

首先,不要对关节使用这种老式语法。

这里有一个查询可以解决你的问题:

SELECT R.id
    ,R.Name
    ,R.Address
    ,R.city
    ,R.Rating
    ,R.Latitude
    ,R.Longitude
    ,A.AreaName
    ,M.Price
    ,R.Veg_NonVeg
    ,COUNT(RV.id) AS numOfReviews
FROM restaurants R
INNER JOIN categories C ON C.restaurant_id = R.id
INNER JOIN menus M ON M.category_id = C.id
INNER JOIN areas A ON A.AreaId = R.AreaId
LEFT JOIN reviews RV ON RV.restaurant_id = R.id
WHERE M.ItemName = 'tiramisu'
GROUP BY R.id, R.Name, R.Address, R.city, R.Rating, R.Latitude, R.Longitude, A.AreaName, M.Price, R.Veg_NonVeg

我使用了显式的INNER JOIN 语法而不是你的老派语法,并且我用表reviews 修改了关节以获得预期的结果。使用聚合函数COUNT 需要GROUP BY 子句,每一行将按枚举列分组(除函数使用的列之外的每一列)。

这是另一个简化GROUP BY 子句并允许修改SELECT 语句的解决方案,而不必担心每个列都需要成为GROUP BY 子句的一部分:

SELECT R.id
    ,R.Name
    ,R.Address
    ,R.city
    ,R.Rating
    ,R.Latitude
    ,R.Longitude
    ,A.AreaName
    ,M.Price
    ,R.Veg_NonVeg
    ,NR.numOfReviews
FROM restaurants R
INNER JOIN (SELECT R2.id
                ,COUNT(RV.id) AS numOfReviews
            FROM restaurants R2
            LEFT OUTER JOIN reviews RV ON RV.restaurant_id = R2.id
            GROUP BY R2.id) NR ON NR.id = R.id
INNER JOIN categories C ON C.restaurant_id = R.id
INNER JOIN menus M ON M.category_id = C.id
INNER JOIN areas A ON A.AreaId = R.AreaId
WHERE M.ItemName = 'tiramisu'

正如您在此处看到的那样,我在一个简单的子查询上添加了一个新的关节,该子查询执行聚合工作,以便为我提供每家餐厅的预期评论数量。

希望这会对你有所帮助。

【讨论】:

  • 在可能的情况下,不使用 join 语句连接表没有任何问题。争论?
  • @Juru 两种语法在性能方面没有区别,但显式表示法是最佳实践。通过使用这种表示法,您可以分离特定于关节的条件 (ON T1.column1 = T2.column2),当您处理多个表格和复杂条件时,这个独特的参数可能会改变一切。另一个论点是,无论您定义的关节类型如何,您都具有相同的语法 (INNER, LEFT, RIGHT,..)。
  • @JoëlSalamin- 谢谢我试过这个,但现在我写count(rv.id) 时只得到一行。查看我编辑的问题
  • @Juru 这是一个偏好问题,我不会告诉你你做错了,因为你的结果将与我建议的方式完全相同。但是,如果您想了解有关这些最佳做法的更多信息,请查看 weblogs.sqlteam.com/jamesw/archive/2011/10/03/…
  • @Juru 您可以参考:msdn.microsoft.com/en-us/library/dd172122.aspxsqlmag.com/t-sql/t-sql-best-practices-part-1 以查看当前使用的 sql 语法。旧的语法没有被弃用,但我想随着变化移动总是一个更好的做法:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 2013-02-28
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多