【问题标题】:MySQL single query to get the records if any record is active or inactive如果任何记录处于活动状态或不活动状态,MySQL 单一查询以获取记录
【发布时间】:2019-12-21 01:19:42
【问题描述】:

我有一个场景,我有 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 组一样,我应该得到 Group1、Group2 和 Group3 作为结果,因为在第 1 组中有一个活动订阅。如果我查询 Inactive 组,我应该得到 null因为 Group1 有一个有效订阅

【问题讨论】:

  • 问题是什么?有什么不行吗?
  • 我想我理解你的规范,但是如果你根据输入和标准向我们展示预期的输出作为所需的行列表,它会更明显
  • @kerbholz 在这里寻找查询
  • 这应该会产生非活动组:select name from groups where id not in (select group_id from users where sub_status='Active'); 我不认为这应该是一个答案。

标签: php mysql sql database join


【解决方案1】:

您可以按每个组计算活动和非活动记录。之后,您可以按该计数过滤组。例如,您可以使用以下查询找到活动组

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

【讨论】:

  • 不应该是SUM 而不是COUNT 吗?
  • @Pepper 是的,这是错误的。我修好了它。谢谢!
  • 您是否有理由需要数数?仅查找“活动”(IF EXISTS)或“非活动”(IF NOT EXISTS)记录的存在是否就足够了?
【解决方案2】:

您无需加入表格。
使用 EXISTS 表示活动组:

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

并且不存在于非活动组:

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

请参阅demo

【讨论】:

  • 这似乎是一个更正确的答案。由于您指出的原因,我删除了我的。
【解决方案3】:

我想你需要这样的查询:

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

【讨论】:

    【解决方案4】:

    您可以为此使用聚合:

    对于活跃组:

    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 值而不是字符串。

    【讨论】:

    • 字段status 来自哪里?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    相关资源
    最近更新 更多