我有下表:
用户,其中包含以下列:
id: INT
name: VARCHAR
boss_id: INT
首领,其中包含以下列:
id: INT
name: VARCHAR
消息,其中包含以下列:
author_id: INT (reference to users)
body: VARCHAR
type: VARCHAR
messages_targets 包含以下列:
user_id: INT (reference to users)
message_id: INT (reference to messages)
现在,我有以下查询可以正确地向我返回每个老板的用户比例,即收到至少一条“紧急”类型消息的用户所占的百分比查询:
SELECT (COUNT(DISTINCT CASE WHEN messages.type = 'urgent' THEN users.id END)::float / NULLIF(COUNT(DISTINCT users.id)::float, 0)) * 100,
bosses.id
FROM bosses
LEFT JOIN users ON users.boss_id = bosses.id
LEFT JOIN messages_targets ON messages_targets.user_id = users.id
LEFT JOIN messages ON messages.id = messages_targets.message_id
GROUP BY bosses.id
现在,我想修改该查询,以便它也返回我,用户已按老板分组编写的紧急消息数。因此,我已经尝试过:
SELECT (COUNT(DISTINCT CASE WHEN messages.type = 'urgent' THEN users.id END)::float / NULLIF(COUNT(DISTINCT users.id)::float, 0)) * 100 as percentage_received,
COUNT(CASE WHEN authored_messages.type = 'urgent' THEN 1 END) authored_messages_count
bosses.id
FROM bosses
LEFT JOIN users ON users.boss_id = bosses.id
LEFT JOIN messages_targets ON messages_targets.user_id = users.id
LEFT JOIN messages ON messages.id = messages_targets.message_id
LEFT JOIN messages authored_messages ON messages.author_id = users.id
GROUP BY bosses.id
但这不起作用。似乎是重复计算了一些数据。
以下是一些示例数据,并遵循我的预期:
bosses (id, name)
1, John
2, Charles
users (id, name, boss_id)
1, Mai, 1
2, Donald, 1
3, Denver, 2
messages (author_id, body, type)
1, 'message from Mai to Donald', 'urgent'
2, 'message from Donald to Denver', 'normal'
3, 'message from Denver to Mai', 'urgent'
4, 'message from Mai to Donald', 'urgent'
messages_targets (user_id, message_id)
2, 1
3, 2
1, 3
2, 4
我希望得到以下信息:
boss_id, percentage_received, authored_messages
1, 100, 2 # (Both Mai and Donald received urgent messages, and in total there were 2 urgent messages sent)
2, 0, 1 # (Denver did not receive any urgent messages, but he sent one message)
答案 0 :(得分:0)
尝试以下查询。它将两个聚合保持分开,因此它们的连接不会互相影响
SELECT
(
SELECT
COUNT(DISTINCT CASE WHEN messages.type = 'urgent' THEN users.id END)::float /
NULLIF(COUNT(DISTINCT users.id)::float, 0)) * 100
FROM users
JOIN messages_targets ON messages_targets.user_id = users.id
JOIN messages ON messages.id = messages_targets.message_id
WHERE users.boss_id = bosses.id
) percentage_received,
(
SELECT
COUNT(CASE WHEN messages.type = 'urgent' THEN 1 END) authored_messages_count
FROM users
JOIN messages_targets ON messages_targets.user_id = users.id
JOIN messages ON messages.author_id = users.id
WHERE users.boss_id = bosses.id
) authored_messages_count
bosses.id
FROM bosses