MySQL单一查询以获取记录(如果有记录处于活动状态或非活动状态)

时间:2019-08-14 13:12:21

标签: php mysql sql database join

我有一个类似下面的2张桌子的情况

groups

id| name
1 | Group 1
2 | Group 2
3 | Group 3


users

id| name | group_id | sub_status
1 | John | 1        | Active
2 | Doe  | 1        | Inactive
3 | Simon| 2        | Active
4 | David| 3        | Active

现在,我需要选择具有活动或非活动订阅状态的组。 就像我在寻找Active组一样,由于第1组中有一个Active订阅,因此我应该得到的任何单个组都将成为Group1,Group2和Group3。如果我查询Inactive个组,则应该之所以获得null,是因为Group1有一个有效的订阅

4 个答案:

答案 0 :(得分:2)

您可以按组统计活动和非活动记录。之后,您可以按该计数过滤组。例如,您可以通过以下查询找到活动组

SELECT 
 groups.id,
 groups.name,
 sum(IF(users.sub_status = 'Active', 1, 0)) as active_count 
 sum(IF(users.sub_status = 'Inactive', 1, 0)) as inactive_count  
FROM groups
LEFT JOIN users ON users.group_id = group.id
GROUP BY groups.id, groups.name
HAVING active_count > 0

和无效的组:

SELECT 
 groups.id,
 groups.name,
 sum(IF(users.sub_status = 'Active', 1, 0)) as active_count 
 sum(IF(users.sub_status = 'Inactive', 1, 0)) as inactive_count  
FROM groups
LEFT JOIN users ON users.group_id = group.id
GROUP BY groups.id, groups.name
HAVING active_count = 0

答案 1 :(得分:1)

您不需要加入表格。
对于活动组具有EXISTS:

select g.* from groups g
where not exists (
  select 1 from users
  where group_id = g.id and sub_status = 'Active'
);

对于不活动的组不存在:

library(tidyverse)

first_tbl <- 
tibble(mydata) %>% 
  filter(str_detect(g, "[0-9]+\\/(.*)[0-9]$")) %>% #find only rows that start with date and end with number
  mutate(g = str_replace_all(g, " - ", "-")) %>% #remove empty space from dashes, since we want to split by spaces
  separate(g, into = c("date", "time", LETTERS[1:8]), sep = " ") 

请参见demo

答案 2 :(得分:0)

我想您需要这样的查询:

select g.id, 
       case when count(case when u.sub_status = 'Inactive' then 1 end)=1 and 
                 count(case when u.sub_status = 'Active' then 1 end) > 0
            then
         null
       else  
         g.name
       end inactive_case,
       case when count(case when u.sub_status = 'Active' then 1 end) = 1 then
         g.name
       end active_case
  from groups g
  left join users u on u.group_id = g.id
 group by g.id, g.name;

 id inactive_case   active_case
 1                  Group 1
 2  Group 2         Group 2
 3  Group 3         Group 3

Demo

答案 3 :(得分:0)

您可以为此使用聚合:

对于活动组:

select u.group_id
from users u
group by u.group_id
having min(u.sub_status) = 'active';    -- any active member

对于非活动状态:

select u.group_id
from users u
group by u.group_id
having min(u.sub_status) = 'inactive';  -- all inactive

这使用了'active' > 'inactive'这个事实。为此,我建议使用0/1值而不是字符串。