|
我有一个名为“工作”的表。对于特定用户,作业可以是活动的,已归档的,过期的,待处理的或已关闭的。现在,每个页面请求都生成5个COUNT查询,为了进行优化,我试图将其减少为单个查询。到目前为止,这是我所拥有的,但这仅比5个单独的查询要快。请注意,我已经简化了每个子查询的条件,以使其更易于理解,但是完整查询的行为相同。 O9 c0 q2 ]/ c
有没有一种方法可以在不使用无效子查询的情况下在同一查询中获得这5个计数?+ O# x' w) ^" g" f* }7 Q
SELECT
% t0 n6 Y$ u7 f" i (SELECT count(*)
. a1 F* U% k' ^ M [. m, v FROM "jobs"
; m' P. f1 J% ? WHERE! l. X" H5 U0 G" ?) D7 z
jobs.creator_id = 5 AND
; C) l9 J" w0 X: i jobs.status_id NOT IN (8,3,11) /* 8,3,11 being 'inactive' related statuses *// S; \1 j' Z' i- c
) AS active_count, " I2 T @ M! f* ]& j) m+ |
(SELECT count(*)- _7 i0 \! f! Q9 }
FROM "jobs"
- [- m, U" ?5 l5 ? WHERE
) x3 D M! ]; r+ d8 u% p jobs.creator_id = 5 AND2 [0 C/ d! }' b2 o
jobs.due_date 继续进行另外2个子查询,但我认为您明白了。
2 q0 ?$ d0 T8 ~0 k是否有一种更简单的方法来收集此数据,因为它与Jobs表中的同一数据子集基本相差5个不同的COUNT?2 \, N3 O: x- T4 _$ x7 Z. a
数据子集为“ creator_id =
% U; z" p5 _, M2 O- `1 Q( ?5”,此后每个计数基本上只是1-2个附加条件。请注意,现在我们正在使用Postgres,但可能会在不久的将来转向MySQL。因此,如果您可以提供与ANSI兼容的解决方案,我将不胜感激 & l6 b7 U7 F$ o: L
+ w9 l) b# M4 R
解决方案:# |( Z' R$ V) W
1 m+ P! K; ^& {+ a& t; g; d' Q; \( G( j0 A: l
% ~; E, r" p- y8 q- j9 u8 T 这是典型的解决方案。使用case语句来分解不同的条件。如果一条记录满足,则得到1,否则得到0。然后SUM对值执行a
7 D3 ^+ b, {2 o w+ [ SELECT
6 B( K8 s9 g6 z% {+ _8 b SUM(active_count) active_count,& d3 a1 n3 u8 ]
SUM(overdue_count) overdue_count- ]+ _0 ? ^& t$ K4 k; V
SUM(due_today_count) due_today_count
% ^7 I: S) ~4 k B5 u% |5 v' f FROM 7 C7 A5 u6 h/ ^7 G/ C! `: G- j
(
! U7 k$ }- Y( L T; I SELECT
: t1 k6 y( H5 R$ x CASE WHEN jobs.status_id NOT IN (8,3,11) THEN 1 ELSE 0 END active_count,! Q4 N0 P" J6 @2 Z4 W8 v
CASE WHEN jobs.due_date UPDATE如前所述,当0记录作为t返回时,此结果将作为所有值中Null的单个结果。您有三个选择
" q' u& r4 o) ^3 f8 y! Q1)添加一个Haveing子句,以便您没有返回记录,而不是所有NULLS的结果
$ l/ z* ^) K8 b% E HAVING SUM(active_count) is not null$ U, z/ V! q- p9 F& @8 W* c
2)如果您希望返回所有零,则可以对所有总和加总
& K. x1 z' h; t/ b例如
: r- P- N! x7 ]! `- \ SELECT
4 S4 Y* k7 U7 ?# {3 o; T4 O COALESCE(SUM(active_count)) active_count,9 s0 X# U) } z6 S9 {
COALESCE(SUM(overdue_count)) overdue_count; K$ V, U5 I* I! ~/ w
COALESCE(SUM(due_today_count)) due_today_count6 C7 Z% m8 w5 x
3)利用COUNT(NULL) = 0sbarro所展示的事实。您应该注意,非空值可以是任何数字,而不必为1
2 ?, N- d& V' s例如
0 A7 a- a" ^5 U7 f. p SELECT( g2 b4 F8 I# x& `+ K% N; u. V
COUNT(CASE WHEN * G; [3 W' A0 E
jobs.status_id NOT IN (8,3,11) THEN 'Manticores Rock' ELSE NULL
5 t0 l! W, n2 B/ ? END) as [active_count] |
|