SQL加入聚合数据

时间:2014-04-25 20:44:42

标签: mysql pdo

我有两个SQL表。

USERS

ID   |  USERNAME
001  |  Tom 
002  |  Jane
003  |  Peter
004  |  Mariah

产品

ID   |   PR_NAME   |  USERID
01   |   Apple     |   002
02   |   Pear      |   001
03   |   Tomato    |   002
04   |   Apple     |   003
05   |   Tomato    |   001
06   |   Apple     |   001

如果我在表单/列表/应用程序中选择“Apple”,我想看看谁购买了“Apple”以及这些人购买了多少产品:

USERID | USERNAME | NUM_PRODUCTS_BOUGHT
001    |  Tom     |          3
002    |  Jane    |          2
003    |  Peter   |          1

我尝试的是

SELECT 
   USERS.ID, USERS.USERNAME, 
   COUNT(PRODUCTS.PR_NAME) AS NUM_PRODUCTS_BOUGHT 
FROM 
   USERS 
LEFT JOIN 
   PRODUCTS ON PRODUCTS.USERID = USERS.ID 
WHERE 
   PRODUCTS.PR_NAME = "Apple" 
GROUP BY 
   USERS.ID

但是它给我错误的数字来自NUM_ALL(1),如

ID     | USERNAME | NUM_PRODUCTS_BOUGHT
001    |  Tom     |          1
002    |  Jane    |          1
003    |  Peter   |          1

我可以通过3种方式得到这个结果,但无法得到我想要的结果。

4 个答案:

答案 0 :(得分:1)

我认为你应该试试一个条款。我还没有对此进行测试,但它应该有效:

SELECT 
   USERS.ID, USERS.USERNAME, 
   COUNT(PRODUCTS.PR_NAME) AS NUM_PRODUCTS_BOUGHT 
FROM 
   USERS 
LEFT JOIN 
   PRODUCTS ON PRODUCTS.USERID = USERS.ID 
GROUP BY 
   USERS.ID
HAVING 
   SUM(CASE WHEN PRODUCTS.PR_NAME = "Apple" THEN 1 ELSE 0 END) > 0

答案 1 :(得分:0)

如果问题是您缺少“Mariah”,这是因为where子句正在撤消left outer join。将条件移动到on子句:

SELECT u.ID, u.USERNAME, COUNT(p.PR_NAME) AS NUM_PRODUCTS_BOUGHT 
FROM USERS u LEFT JOIN 
     PRODUCTS p
     ON p.USERID = u.ID AND
        p.PR_NAME = 'Apple'
GROUP BY u.ID;

注意:在某些数据库中,您需要在u.USERNAME子句中包含group by。但是,假设USERS.ID是唯一的,则此用法与ANSI标准一致。

答案 2 :(得分:0)

你可以在图层中考虑它......

首先,您有一个产品

--q1
select * from PRODUCTS where PR_NAME = "Apple"

然后,您想了解带来该产品的用户

--q2
select * from users where
id in (
--q1
select USERID from PRODUCTS where PR_NAME = "Apple"
)

现在,对于想要了解他/她购买了多少产品的用户

--q3
select userid, count(id) cnt from PRODUCT group by userid

最后你想要结合q2和q3的输出:

select u.id, u.USERNAME, cnt.cnt from users u inner join 
(    --q3
select userid, count(id) cnt from PRODUCT  group by userid
) cnt on u.ID = cnt.userid
where
u.id in (
--q1
select USERID from PRODUCTS where PR_NAME = "Apple"
)

优化:

select u.id, u.USERNAME, cnt.cnt from users u inner join 
(    --q3
select userid, count(id) cnt from PRODUCT  group by userid
) cnt on u.ID = cnt.userid
inner join product p on u.id = p.userid
where
p.pr_name = 'Apple'

答案 3 :(得分:0)

试试这个:

SELECT U.ID, U.USERNAME, COUNT(P2.PR_NAME) NUM_PRODUCTS_BOUGHT
FROM USERS U
  JOIN PRODUCTS P1
    ON U.ID = P1.USERID
  JOIN PRODUCTS P2
    ON P1.USERID = P2.USERID
WHERE P1.PR_NAME = 'Apple'
GROUP BY U.ID, U.USERNAME

以下是SQL Server的 SQL FIDDLE