将SELECT与UNION一起使用

时间:2013-12-03 13:26:12

标签: sql

CREATE TABLE members
(
name        varchar(60),
ID          char(6)         PRIMARY KEY
); 


CREATE TABLE ratings
(
memberID    char(6)            REFERENCES members(ID),
rating      SMALLINT CHECK(rating >= 1 AND rating <= 8),
gameID      integer            REFERENCES games(ID),
    PRIMARY KEY (memberID, gameID)
);

大家好,我正在尝试列出所有评分过游戏的会员,并显示最高费率,最低费率,平均费率以及评分次数。

我试过了:

    (SELECT MAX(rating), MIN(rating), AVG(rating), COUNT(rating), name
FROM ratings, members
WHERE ratings.memberID = members.ID
GROUP BY name) 
    UNION
    (SELECT   MAX(rating), MIN(rating),  AVG(rating),COUNT(distinct rating), name
FROM ratings, members
WHERE 
members.ID NOT IN (SELECT  memberID
FROM ratings, members
WHERE ratings.memberID = members.ID)
GROUP BY name);

这第一部分给了我一个正确的价值观;它给出了正确的名称,后跟Max,min和count,以及平均值。但第二部分给出了正确的名称,但错误的Max,Min,Average值。对于没有评价任何游戏的所有成员,它给出最大值9和最小值2!哪个不是真的。我如何修复第二部分,所以它给出的值为零而不是9和2?

2 个答案:

答案 0 :(得分:1)

我认为您可以使用LEFTRIGHT加入

来获取您要查找的结果集
SELECT 
    M.name,
    MAX(rating),
    MIN(rating),
    AVG(rating),
    COUNT(rating)
FROM
    [members] M
LEFT OUTER JOIN
    [ratings] R
ON 
    M.ID = R.memberID
GROUP BY 
    M.name

然后会产生类似

的结果
name    max    | min   | average  |  count
name1    8     | 2     |    5     |   3
name2    NULL  | NULL  |  NULL    |   0

答案 1 :(得分:0)

我使用INNER JOIN语法重写了该查询,因为更清楚的是为什么连接会带来意想不到的结果。正如你所写的那样,第二个查询会将所有结果加入到所有没有结果的成员中,每个:

SELECT   MAX(rating), MIN(rating),  AVG(rating),COUNT(distinct rating), name
FROM ratings, members
WHERE 
members.ID NOT IN (SELECT  memberID
FROM ratings, members
WHERE ratings.memberID = members.ID)

我怀疑你是在追求更像:

SELECT      MAX(rating), 
            MIN(rating), 
            AVG(rating), 
            COUNT(rating), 
            name

FROM        ratings

INNER JOIN  members
    ON      ratings.memberID = members.ID

GROUP BY    name

UNION

SELECT      MAX(rating), 
            MIN(rating),  
            AVG(rating),
            COUNT(distinct rating), 
            name

FROM        ratings

WHERE       ratings.memberID NOT IN (SELECT  memberID FROM members)

GROUP BY    name