将所有记录保留在“WHERE IN()”子句中,即使找不到它们也是如此

时间:2012-11-20 22:41:07

标签: mysql

我有以下mysql查询:

SELECT id, sum(views) as total_views
FROM table
WHERE id IN (1,2,3)
GROUP BY id
ORDER BY total_views ASC

如果在数据库中只找到id 1,3,我仍然希望id 2出现,total_views设置为0.

有没有办法做到这一点?这不能使用任何其他表。

6 个答案:

答案 0 :(得分:7)

此查询使用由联合组成的子查询对可能的ID列表进行硬编码...然后将这组ID连接到包含要计数的信息的表中。

即使没有出现,也会在结果中保留ID:

SELECT ids.id, sum(views) as total_views
FROM (
    SELECT 1 AS ID 
    UNION ALL SELECT 2 AS ID 
    UNION ALL SELECT 3 AS ID 
) ids 
LEFT JOIN table
    ON table.ID = ids.ID
GROUP BY ids.id
ORDER BY total_views ASC

或者,如果您有numbers table,则可以执行以下查询:

SELECT numbers.number, sum(views) as total_views
FROM
    numbers
    LEFT JOIN table
        ON table.ID = ids.ID
WHERE numbers.number IN (1, 2, 3)
GROUP BY numbers.number
ORDER BY total_views ASC

答案 1 :(得分:3)

这是迈克尔解决方案的替代方案(不是一个糟糕的解决方案,请注意 - 即使是“很多”的ID),只要你不是要查询群集。

create temporary table __ids (
  id int unsigned primary key
) engine=MEMORY;

insert into __ids (id) values
  (1),
  (2),
  (3)
;

SELECT table.id, sum(views) as total_views
FROM __ids left join table using (id)
GROUP BY table.id
ORDER BY total_views ASC

如果您的查询变得复杂,我甚至可以设想它以这种方式更有效地运行。但是,如果我是你,我会使用真实数据将这个选项与Michael的ad-hoc UNION'ed表选项进行基准测试。

答案 2 :(得分:1)

在@ Michael的回答中,如果你有一个包含你关心的ID的表,你可以用它作为“ids”代替迈克尔的内联数据。

答案 3 :(得分:0)

检查这个小提琴...... http://www.sqlfiddle.com/#!2/a9392/3

Select B.ID, sum(A.views) sum from tableB B
 left outer join tableA A
 on B.ID = A.ID
group by A.ID

还检查 http://www.sqlfiddle.com/#!2/a1bb7/1

答案 4 :(得分:0)

试试这个

    SELECT id 
                (CASE 1
                    IF EXISTS THEN  views = mytable.views END
                    IF NOT EXIST THEN views = 0 END
                CASE 2
                    IF EXISTS THEN  views = mytable.views END
                    IF NOT EXIST THEN views = 0 END
                CASE 3
                    IF EXISTS THEN  views = mytable.views END
                    IF NOT EXIST THEN views = 0 END), sum(views) as total_views
    FROM mytable
    WHERE id IN (1,2,3)
    GROUP BY id
    ORDER BY total_views ASC

答案 5 :(得分:0)

是否必须是行,或者您是否可以透过数据为每个ID提供一行和一列?

SELECT
  SUM(IF (id=1, views, 0)) views_1,
  SUM(IF (id=2, views, 0)) views_2,
  SUM(IF (id=3, views, 0)) views_3
FROM table