如何计算所有满足MySQL条件的不同值?

Fun*_*zed 14 mysql sql group-by count distinct

我正在尝试编写一个查询来查找特定字段中的不同值,计算该值的出现次数,其中该特定值的所有实例都满足另一个列值,然后显示结果如下(更多解释为跟随):

示例db:

RowId    Status       MemberIdentifier
-----    ------       ----------------
1       In Progress   111111111
2       Complete      123456789
3       Not Started   146782452
4       Complete      111111111
5       Complete      123456789
6       Not Started   146782452
7       Complete      111111111
Run Code Online (Sandbox Code Playgroud)

期望的结果:

Status         MemberIdentifierCount 
------         ---------------------- 
Not Started    1
In Progress    1
Complete       1
Run Code Online (Sandbox Code Playgroud)

在上面的查询中,计算并显示具有给定状态的不同MemberIdentifier的数量.如果MemberIdentifier有两行,状态为"完成",但其中一行状态为"正在进行",则将其分组并计为正在进行中(即,MemberIdentifier = 111111111).要将MemberIdentifier分组并计为完成,其所有行的状态必须为"Complete"(即MemberIdentifier = 123456789).任何见解将不胜感激(MySQL新手).

Tho*_*ner 10

每个MemberIdentifier找到您认为合适的状态,例如,'In Progress'胜过'Complete''Not Started'.'Not Started'胜利'Complete'.为此使用条件聚合.

select status, count(*)
from
(
  select 
    case when sum(status = 'In Progress') > 0 then 'In Progress'
         when sum(status = 'Not Started') > 0 then 'Not Started'
         else 'Complete'
    end as status
  from mytable
  group by memberidentifier
) statuses
group by status;
Run Code Online (Sandbox Code Playgroud)


Ric*_*mes 6

SELECT max_status AS Status
     , COUNT(*) AS ct
    FROM (
        SELECT MAX(Status) AS max_status
            FROM tbl
            GROUP BY MemberIdentifier
         ) AS a
    GROUP BY max_status;
Run Code Online (Sandbox Code Playgroud)

这利用了这些字符串的比较:"进行中">"完成".在这样做时,它会对具有多个状态的任何其他成员执行随机操作.


Ste*_*ers 5

SQL

SELECT AdjustedStatus AS Status,
       COUNT(*) AS MemberIdentifierCount
FROM
(SELECT IF(Status='Complete',
           IF(EXISTS(SELECT Status
                     FROM tbl t2
                     WHERE t2.Status = 'In Progress'
                       AND t2.MemberIdentifier = t1.MemberIdentifier),
              'In Progress',
              'Complete'),
           Status) AS AdjustedStatus,
        MemberIdentifier
 FROM tbl t1
 GROUP BY AdjustedStatus, MemberIdentifier) subq
GROUP BY AdjustedStatus;
Run Code Online (Sandbox Code Playgroud)

在线演示

http://rextester.com/FFGM6300

说明

第一个IF()函数检查状态是否为"完成",如果是,则检查是否存在具有相同MemberIdentifier但状态为"正在进行" 的另一个记录:这是通过完成的IF(EXISTS(SELECT...))).如果找到,则将"正在进行"状态分配给该AdjustedStatus字段,否则AdjustedStatus从(未调整的)Status值设置.

调整后的状态已经得出这样每个表中的行,GROUP BYAdjustedStatusMemberIdentifier为了得到这两个字段值的所有独特的组合.然后将其制作为子查询 - 别名为subq.然后聚合(GROUP BY)AdjustedStatus并计算出现次数,即MemberIdentifier每次出现的唯一s数.


Ram*_*esh 5

我假设您有2个表格如下

CREATE TABLE table1 (RowId INT PRIMARY KEY, MemberIdentifier VARCHAR(255));
INSERT INTO table1 (RowId, MemberIdentifier)
VALUES
(1,'111111111'), (2, '123456789'), (3, '146782452'), (4, '111111111'),(5,'123456789'), (6,'146782452'), (7,'111111111');


CREATE TABLE table2 (RowId INT PRIMARY KEY, Status VARCHAR(255));
INSERT INTO table2 (RowId, Status)
VALUES
(1,'In Progress'), (2,'Complete'   ), (3,'Not Started'), (4,'Complete'   ), (5,'Complete'   ), (6,'Not Started'), (7,'Complete'   );
Run Code Online (Sandbox Code Playgroud)

假设您在这些表中没有数百万条记录,您可以使用下面的查询来实现您想要的目标.

SELECT CASE WHEN not_started.Status = 'Not Started' 
            THEN 'Not Started' 
            WHEN in_progress.Status = 'In Progress' 
            THEN 'In Progress' 
            WHEN complete.Status = 'Complete' 
            THEN 'Complete' 
       END AS over_all_status,
       COUNT(*) AS MemberIdentifierCount
  FROM  (SELECT DISTINCT t1.MemberIdentifier
          FROM table1 t1) main
        LEFT OUTER JOIN   
            (SELECT DISTINCT t1.MemberIdentifier, t2.Status
              FROM table1 t1,
                   table2 t2 
             WHERE t1.RowId = t2.RowId
               AND t2.Status = 'In Progress') in_progress
            ON (main.MemberIdentifier = in_progress.MemberIdentifier)
        LEFT OUTER JOIN
            (SELECT DISTINCT t1.MemberIdentifier, t2.Status
              FROM table1 t1,
                   table2 t2 
             WHERE t1.RowId = t2.RowId
               AND t2.Status = 'Not Started') not_started
        ON (main.MemberIdentifier = not_started.MemberIdentifier)
        LEFT OUTER JOIN
            (SELECT DISTINCT t1.MemberIdentifier, t2.Status
              FROM table1 t1,
                   table2 t2 
             WHERE t1.RowId = t2.RowId
               AND t2.Status = 'Complete') complete
        ON (main.MemberIdentifier = complete.MemberIdentifier)
GROUP BY over_all_status;
Run Code Online (Sandbox Code Playgroud)

基本上,查询为每个MemberIdentifier创建一条记录,其中包含所有可能的三种状态.然后,它根据总体状态对结果进行分组并输出计数.

查询的输出是

在此输入图像描述