在一个巨大的SQL查询上,如下所示:
SELECT
...
(SELECT COUNT(*) FROM table1 WHERE field = 'bar' AND table1.table0_id = table0.id)
(SELECT COUNT(*) FROM table1 WHERE field = 'foobar' AND table1.table0_id = table0.id)
(SELECT COUNT(*) FROM table1 WHERE field = 'foo' AND table1.table0_id = table0.id)
...
FROM table0;
有没有办法避免在table0上为每次迭代运行3个查询?
由于
答案 0 :(得分:3)
您可以使用条件聚合来简化查询
这是正确的方法
SELECT coalesce(b_count,0),
coalesce(fb_count,0),
coalesce(f_count,0)
FROM table0
LEFT JOIN (SELECT table1.table0_id,
Count(CASE WHEN field = 'bar' THEN 1 END) AS b_count,
Count(CASE WHEN field = 'foobar' THEN 1 END) AS fb_count,
Count(CASE WHEN field = 'foo' THEN 1 END) AS f_count,
FROM table1
WHERE field IN ( 'bar', 'foobar', 'foo' )
GROUP BY table1.table0_id) table1
ON table1.table0_id = table0.id
答案 1 :(得分:3)
Postgres 9.4 +
select
count(table0.id) filter (where field = 'bar'),
count(table0.id) filter (where field = 'foobar'),
count(table0.id) filter (where field = 'foo')
from table1
left join table0 on table1.table0_id = table0.id
group by table0.id;
答案 2 :(得分:2)
我认为你不需要table0
。您可以使用条件聚合:
SELECT table1.table0_id,
SUM(CASE WHEN field = 'bar' THEN 1 ELSE 0 END) as bar,
SUM(CASE WHEN field = 'foobar' THEN 1 ELSE 0 END) as foobar,
SUM(CASE WHEN field = 'foo' THEN 1 ELSE 0 END) as foo
FROM table1
GROUP BY table1.table0_id;
如果table0
中的值不在table1
中,您可以使用left join
:
SELECT table2.id,
SUM(CASE WHEN field = 'bar' THEN 1 ELSE 0 END) as bar,
SUM(CASE WHEN field = 'foobar' THEN 1 ELSE 0 END) as foobar,
SUM(CASE WHEN field = 'foo' THEN 1 ELSE 0 END) as foo
FROM table0 LEFT JOIN
table1
ON table0.id = table1.table0_id
GROUP BY table2.id;
您还可以将SELECT
缩短为:
SUM((field = 'bar')::int) as bar,
SUM((field = 'foobar')::int) as foobar,
SUM((field = 'foo')::int) as foo