使用重复的行数据连接 table 时如何获得正确的 SUM()?
How to get correct SUM() when joining table with duplicated row data?
目前我有3个table,第一个table 'Users'包含id
和user_name
。第二个 table 'listings' 包含 refno
和 agent_id
。我的第三个 table 'logs' 包含 refno
和 status
。现在我想在他们的状态旁边显示一个人的名字。所以基本上我想要日志中的状态条目数并将它们各自的用户名放在它旁边。
为此,我必须参考 'logs' 的 refno
到 'listings' 的 refno
和 'listings' 的 agent_id
到id
个 'Users'。为此,我使用了以下语句:
select SUM(CASE WHEN status = 'Draft' THEN 1 END) AS draft,
SUM(CASE WHEN status = 'Publish' THEN 1 END) AS publish,
u.name
from logs t
inner join listings l on t.refno = l.refno
inner join users u on l.agent_id=u.id
但是这个 returns 输出如下:
错了,我想要的输出是这样的:
Draft
Publish
Name
1
1
Jason
0
1
Jam
我添加了一个带有数据的 sqlfiddle 以使参考更容易理解:http://sqlfiddle.com/#!9/22b6e4/5
更新:
根据您在下面的评论,您需要首先在 FROM
子句中创建伪 table,该子句必须包含所有必要的数据才能获得所需的结果。
下面的子查询创建了一个包含所有必需数据的伪 table。
SELECT u.id,
u.name,
t.status,
t.refno
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id = u.id
GROUP BY t.refno, u.name, t.status;
您只需将上述查询作为子查询包装在原始查询的 FROM
子句中。
所以这是获得所需输出的最终查询。
SELECT SUM(CASE WHEN tab.status = 'Draft' THEN 1 ELSE 0 END) AS draft,
SUM(CASE WHEN tab.status = 'Publish' THEN 1 ELSE 0 END) AS publish,
tab.name
FROM (SELECT u.id,
u.name,
t.status,
t.refno
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id = u.id
GROUP BY t.refno, u.name, t.status) AS tab
GROUP BY tab.name
ORDER BY tab.id;
原答案:
您需要添加 GROUP BY
子句以根据所需参数对结果进行分组。
在这里您可以按 l.agent_id
或 u.id
.
分组
我注意到的另一件事是你需要在你的 SUM
声明中添加一个 ELSE
子句到 return 0
以防意外 status
return来自查询。
像这样:
SUM(CASE WHEN status = 'Publish' THEN 1 ELSE 0 END)
所以你的最终查询变成这样:
SELECT SUM(CASE WHEN status = 'Draft' THEN 1 ELSE 0 END) AS draft,
SUM(CASE WHEN status = 'Publish' THEN 1 ELSE 0 END) AS publish,
u.name
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id=u.id
GROUP BY u.id;
需要克服的明显问题是您的列表中有非唯一数据 table -- 这会扭曲您的总和。
您只需在唯一的行上加入,这样您就不会多次计算随后加入的行。
SELECT u.id,
u.name,
SUM(status = 'Draft') AS draft,
SUM(status = 'Publish') AS publish
FROM users AS u
JOIN (SELECT DISTINCT * FROM listings) AS l ON u.id = l.agent_id
JOIN logs AS t ON l.refno = t.refno
GROUP BY u.id
我更喜欢在结果集中包含 id,因为名称通常不是唯一的。
目前我有3个table,第一个table 'Users'包含id
和user_name
。第二个 table 'listings' 包含 refno
和 agent_id
。我的第三个 table 'logs' 包含 refno
和 status
。现在我想在他们的状态旁边显示一个人的名字。所以基本上我想要日志中的状态条目数并将它们各自的用户名放在它旁边。
为此,我必须参考 'logs' 的 refno
到 'listings' 的 refno
和 'listings' 的 agent_id
到id
个 'Users'。为此,我使用了以下语句:
select SUM(CASE WHEN status = 'Draft' THEN 1 END) AS draft,
SUM(CASE WHEN status = 'Publish' THEN 1 END) AS publish,
u.name
from logs t
inner join listings l on t.refno = l.refno
inner join users u on l.agent_id=u.id
但是这个 returns 输出如下:
错了,我想要的输出是这样的:
Draft | Publish | Name |
---|---|---|
1 | 1 | Jason |
0 | 1 | Jam |
我添加了一个带有数据的 sqlfiddle 以使参考更容易理解:http://sqlfiddle.com/#!9/22b6e4/5
更新:
根据您在下面的评论,您需要首先在 FROM
子句中创建伪 table,该子句必须包含所有必要的数据才能获得所需的结果。
下面的子查询创建了一个包含所有必需数据的伪 table。
SELECT u.id,
u.name,
t.status,
t.refno
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id = u.id
GROUP BY t.refno, u.name, t.status;
您只需将上述查询作为子查询包装在原始查询的 FROM
子句中。
所以这是获得所需输出的最终查询。
SELECT SUM(CASE WHEN tab.status = 'Draft' THEN 1 ELSE 0 END) AS draft,
SUM(CASE WHEN tab.status = 'Publish' THEN 1 ELSE 0 END) AS publish,
tab.name
FROM (SELECT u.id,
u.name,
t.status,
t.refno
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id = u.id
GROUP BY t.refno, u.name, t.status) AS tab
GROUP BY tab.name
ORDER BY tab.id;
原答案:
您需要添加 GROUP BY
子句以根据所需参数对结果进行分组。
在这里您可以按 l.agent_id
或 u.id
.
我注意到的另一件事是你需要在你的 SUM
声明中添加一个 ELSE
子句到 return 0
以防意外 status
return来自查询。
像这样:
SUM(CASE WHEN status = 'Publish' THEN 1 ELSE 0 END)
所以你的最终查询变成这样:
SELECT SUM(CASE WHEN status = 'Draft' THEN 1 ELSE 0 END) AS draft,
SUM(CASE WHEN status = 'Publish' THEN 1 ELSE 0 END) AS publish,
u.name
FROM logs t
INNER JOIN listings l ON t.refno = l.refno
INNER JOIN users u ON l.agent_id=u.id
GROUP BY u.id;
需要克服的明显问题是您的列表中有非唯一数据 table -- 这会扭曲您的总和。
您只需在唯一的行上加入,这样您就不会多次计算随后加入的行。
SELECT u.id,
u.name,
SUM(status = 'Draft') AS draft,
SUM(status = 'Publish') AS publish
FROM users AS u
JOIN (SELECT DISTINCT * FROM listings) AS l ON u.id = l.agent_id
JOIN logs AS t ON l.refno = t.refno
GROUP BY u.id
我更喜欢在结果集中包含 id,因为名称通常不是唯一的。