我在架构中有以下结构:
------------------------------- ----------------------------
| m_user | | person |
------------------------------- ----------------------------
| UUID | ID | PLATFORM | | ID | NAME | EMAIL |
| 456789 | 22222 | TG | | 22222 | JOSEPH | J@CM.CO |
| 987654 | 22222 | MS | | 85858 | MARKUS | M@GM.CO |
| 948576 | 85858 | TG | | 36363 | ANDREA | A@GM.CO |
------------------------------- ----------------------------
-------------------------------------------------
| plan |
-------------------------------------------------
| ID | HOURS | DATE | CLIENT |
| 22222 | 72 | 2017-12-05 | CLIENT11 |
| 22222 | 88 | 2017-12-25 | CLIENT11 |
| 85858 | 48 | 2017-12-05 | CLIENT12 |
-------------------------------------------------
我需要返回为SUM
表中存在的每个用户计划的HOURS
m_user
。 m_user
每个平台只允许一个ID
:同一个用户可以在两个平台上,但拥有适用于这两个平台的唯一ID。
当结果显示重复SUM
值时会出现问题,因为ID在m_user
表中出现两次。这是查询:
SELECT ps.id
ps.name,
ps.email,
SUM(pl.hours) AS hours
FROM schema.person AS ps
JOIN schema.m_user AS usr ON ps.id = usr.id
JOIN schema.plan AS pl ON usr.id = pl.id -- Here is the problem, I think
WHERE pl.client = 'CLIENT11' AND
pl.date BETWEEN '2017-12-01' AND '2017-12-31'
GROUP BY id, name, email;
我尝试过使用DISTINCT
和DISTINCT ON (usr.id)
,但给出的结果是相同的。
以下是我得到的结果:
--------------------------------------
| ID | NAME | EMAIL | HOURS |
--------------------------------------
| 22222 | JOSEPH | J@CM.CO | 320 | -- <- 320 instead of 160
| ... | .... | .... | ... |
--------------------------------------
我是SQL的新手,所以我认为这是一个简单的错误,我现在无法想象,我也尝试使用OVER (PARTITION BY usr.id)
AND LIMIT 1
但我再次获得320显示22222
的行。我是否需要使用CTE来执行此查询?我希望你能帮帮我,谢谢(我目前正在使用PostgreSQL,但我认为这个问题一般适用于SQL,所以我设置了SQL标签)。
答案 0 :(得分:1)
删除了m_user上的联接。在m_user表上使用子查询来查找用户列表。
SELECT ps.id,
ps.name,
ps.email,
SUM(pl.hours) AS hours
FROM schema.person AS ps
JOIN schema.plan AS pl ON ps.id = pl.id
WHERE pl.client = 'CLIENT11' AND
pl.date BETWEEN '2017-12-01' AND '2017-12-31'
AND ps.id IN ( SELECT usr.id FROM schema.m_user AS usr )
GROUP BY ps.id, ps.name, ps.email;
sqlfiddle:sqlfiddle.com/#!17/5996e/1
答案 1 :(得分:0)
您可以将此短语称为:
SELECT ps.id, ps.name, ps.email, SUM(pl.hours) AS hours
FROM schema.person ps JOIN
(SELECT usr.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) as seqnum
FROM schema.m_user usr
) usr
ON ps.id = usr.id JOIN
schema.plan pl
ON usr.id = pl.id AND seqnum = 1
WHERE pl.client = 'CLIENT11' AND
pl.date BETWEEN '2017-12-01' AND '2017-12-31'
GROUP BY id, name, email;
这为join
选择了一行。