使用多个用户 ID 对 table 进行复杂查询

Complex querying on table with multiple userids

我有一个 table 这样的:

score
id  week  status
1    1     0
2    1     1
3    1     0
4    1     0
1    2     0
2    2     1
3    2     0
4    2     0
1    3     1
2    3     1
3    3     1
4    3     0

我想获取除第 3 周外所有周状态都为零的人的 ID。像这样:

结果:

result:
id   w1.status  w2.status  w3.status
1    0          0          1
3    0          0          1

我有这个查询,但它在较大的数据集上效率极低。

SELECT w1.id, w1.status, w2.status, w3.status
FROM
(SELECT s.id, s.status
FROM score s 
WHERE s.week = 1) w1
LEFT JOIN
(SELECT s.id, s.status
FROM score s 
WHERE s.week = 2) w2 ON w1.id=w2.id
LEFT JOIN
(SELECT s.id, s.status
FROM score s 
WHERE s.week = 3) w3 ON w1.id=w3.id
WHERE w1.status=0 AND w2.status=0 AND w3.status=1

我正在寻找一种更有效的方法来计算上述内容。

您可以使用 not exists 作为

select 
t1.id, 
'0' as `w1_status` , 
'0' as `w2_status`, 
'1' as `w3_status` 
from score t1 
where 
t1.week = 3 
and t1.status = 1 
and not exists( 
  select 1 from score t2 
  where t1.id = t2.id and t1.week <> t2.week and  t2.status  = 1
);

为了获得更好的性能,您可以在 table 中添加索引,如

alter table score add index week_status_idx (week,status);

如果周数是静态的 (1-3),group_concat 可能会被用作 hack..

概念:

SELECT
    id,
    group_concat(status) as totalStatus
    /*(w1,w2=0,w3=1 always!)*/
FROM
    tableName
WHERE
    totalStatus = '(0,0,1)' /* w1=0,w2=1,w3=1 */
GROUP BY
    id
ORDER BY 
    week ASC

(随手写。未测试)

SELECT p1.id, p1.status, p2.status, p3.status
FROM score p1 
JOIN score p2 ON p1.id = p2.id
JOIN score p3 ON p2.id = p3.id
WHERE p1.week = 1
AND p1.status = 0
AND p2.week = 2
AND p2.status = 0
AND p3.week = 3
AND p3.status = 1

试试这个,应该有用

select id
from score
where week in (1, 2, 3)
group by id
having sum(
    case
        when week in (1, 2) and status = 0 then 1
        when week = 3 and status = 1 then 1
        else 0
    end
) = 3

或者更笼统地说...

select id
from score
group by id
having
        sum(case when status = 0 then 1 else 0 end) = count(*) - 1
    and min(case when status = 1 then week else null end) = max(week)