2011-05-02 79 views
6

我绝对与SQL一个小白,我一直在破坏我的头写在PostgreSQL符合下表结构的复杂查询:查询与子查询数,内部连接和组

CREATE TABLE reports 
(
    reportid character varying(20) NOT NULL, 
    userid integer NOT NULL, 
    reporttype character varying(40) NOT NULL, 
) 

CREATE TABLE users 
(
    userid serial NOT NULL, 
    username character varying(20) NOT NULL, 
) 

目标的查询是为每个用户提取大量的报告类型并将其显示在一列中。有三种不同类型的报告。

用一个简单的查询组,通过将解决这个问题,但在不同的行显示出来:

select count(*) as Amount, 
     u.username, 
     r.reporttype 
from reports r, 
    users u 
where r.userid=u.userid 
group by u.username,r.reporttype 
order by u.username 
+1

你期待什么输出? – Ruben 2011-05-02 17:47:18

+0

只有三种不同类型的报告:“类型1”,“类型2”,“类型3”,查询应该在一行中显示用户名,“类型1”报告的数量,“类型2”报告的数量以及“ type3“报告。对不起,混淆 – 2011-05-02 18:22:23

+1

在你的例子中的查询中,你使用c.userid和c.reporttype,但是c来自哪里?您尚未创建任何名为c的别名或名为c的表。 – Ruben 2011-05-02 18:55:19

回答

14
SELECT 
    username, 
    (
    SELECT 
    COUNT(*) 
    FROM reports 
    WHERE users.userid = reports.userid && reports.reporttype = 'Type1' 
) As Type1, 
    (
    SELECT 
    COUNT(*) 
    FROM reports 
    WHERE users.userid = reports.userid && reports.reporttype = 'Type2' 
) As Type2, 
    (
    SELECT 
    COUNT(*) 
    FROM reports 
    WHERE users.userid = reports.userid && reports.reporttype = 'Type3' 
) As Type3 
FROM 
    users 
WHERE 
    EXISTS(
    SELECT 
     NULL 
    FROM 
     reports 
    WHERE 
     users.userid = reports.userid 
) 
+0

这个技巧相当不错,但有没有办法忽略零报告的用户? – 2011-05-02 19:33:19

+0

查看更新的答案 – Magnus 2011-05-02 19:45:37

+0

您不需要更新您的问题,只需将正确答案标记为解决方案即可。 – Magnus 2011-05-02 19:58:49

0

如果你正在寻找的“每用户amountof报告类型”,你会期待对每个用户看一个数字,1,2或3(假设有三种不同类型的报告)。你不会期待reporttype(它只会被计数而不显示),所以你不需要查询中的SELECT或GROUP BY部分的reporttype。

而是使用COUNT(DISTINCT r.reporttype)来计算每个用户使用的不同报告类型的数量。

SELECT 
COUNT(DISTINCT r.reporttype) as Amount 
,u.username 
FROM users u 
INNER JOIN reports r 
ON r.userid=u.userid 
GROUP BY 
u.username 
ORDER BY u.username 
+0

这不是我正在寻找的。只有三种不同类型的报告:“type1”,“type2”,“type3”,查询应该显示一行用户名,“type1”报告的数量,“type2”报告的数量以及“type3” “报道。对困惑感到抱歉。 – 2011-05-02 18:20:59

5
SELECT 
    u.username, 
    COUNT(CASE r.reporttype WHEN 1 THEN 1 END) AS type1Qty, 
    COUNT(CASE r.reporttype WHEN 2 THEN 1 END) AS type2Qty, 
    COUNT(CASE r.reporttype WHEN 3 THEN 1 END) AS type3Qty 
FROM reports r 
    INNER JOIN users u ON r.userid = u.userid 
GROUP BY u.username 

如果您的服务器的SQL方言需要else分支存在于CASE表达式,每END前加ELSE NULL

+0

我upvote,因为我不是子查询bigfan。谢谢。 – 2017-12-08 11:46:12