MySQL联接+位置+分组依据

时间:2019-01-16 19:26:32

标签: mysql join group-by

这里的数据库结构:

turns DB Table
+-----------+-------------+------------+------------+----------------+
| turnNumber| userId      | locationId | status     | itemsPurchased |
+-----------+-------------+------------+------------+----------------+
| 32        | 1           | 1          | 1          | 20             |
| 33        | 2           | 1          | 0          | 0              |
+-----------+-------------+------------+------------+----------------+

locations DB Table
+-----------+---------+---------+
| id        | Address | ZIPCode | 
+-----------+---------+---------+
| 1         | ...     | 12345   | 
| 2         | ...     | 67890   | 
+-----------+---------+---------+

我正在尝试获取每个位置数据(地址,邮政编码...)+每个位置的待处理匝数(状态为0)+每个位置购买的商品总和(即使状态为1,也适用于所有匝)

在这里查询:

SELECT 
    l.*, 
    COUNT(t.id) AS turns,
    SUM(IF(t.itemsPurchased > 0, t.itemsPurchased, 0)) AS items
FROM turns t RIGHT OUTER JOIN locations l
ON t.locationId = l.id          
WHERE t.status = 0 AND
l.ZIPCode = XXXX 
GROUP BY l.id

问题是,当我将t.status条件置于转弯表中且状态为0的情况下没有转弯时,也不会获取位置数据,即使这样,我想所购买商品的计数也只会是转数状态为0且并非所有回合。

我想知道是否有一种方法可以在同一查询中获取所有数据,请帮忙!

编辑:

预期输出如下:

+-----------+-------------+------------+------------+----------------+
| id        | Address     | ZIPCode    | turns      | itemsPurchased |
+-----------+-------------+------------+------------+----------------+
| 1         | ...         | 12345      | 1          | 20             |
+-----------+-------------+------------+------------+----------------+

2 个答案:

答案 0 :(得分:2)

t.status = 0子句中的条件“ WHERE”使联接的“外部”无效。我们可以通过INNER JOIN获得相同的结果。

通过外部联接,locations中所有没有匹配行的行turns中的所有t.列都将返回NULL值。 locations中不匹配的行将被WHERE子句中的条件排除。


请考虑将该条件从外部联接的WHERE子句重新定位到ON子句。

或考虑将条件重新定位为聚合表达式。

例如:

SELECT l.id
     , l.zipcode
     , SUM(IF(t.status = 0, 1, 0)) AS turns
     , SUM(IF(t.status = 0 AND t.itemspurchased > 0, t.itemspurchased, 0)) AS items
 FROM locations l

 LEFT 
 JOIN turns t
   ON t.locationid = l.id
  AND t.status     = 0 

WHERE l.zipcode = XXXX 
GROUP
   BY l.id
    , l.zipcode

答案 1 :(得分:0)

使用左联接并将条件放在不同的位置。

为避免这种情况,通过在LEFT JOIN'd表的WHERE子句中使用一个条件,可以使它生效,因为它是INNER JOIN。

SELECT 
loc.ZIPCode,
COUNT(DISTINCT CASE turns.status WHEN 0 THEN turns.id END) AS turns,
SUM(CASE 
    WHEN turns.status = 1 AND turns.itemsPurchased > 0 
    THEN turns.itemsPurchased 
    ELSE 0 
    END) AS items
FROM locations loc
LEFT JOIN turns ON turns.locationId = loc.id
WHERE loc.ZIPCode = 12345
GROUP BY loc.id, loc.ZIPCode