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)
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)
这利用了这些字符串的比较:"进行中">"完成".在这样做时,它会对具有多个状态的任何其他成员执行随机操作.
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)
在线演示
说明
第一个IF()
函数检查状态是否为"完成",如果是,则检查是否存在具有相同MemberIdentifier
但状态为"正在进行" 的另一个记录:这是通过完成的IF(EXISTS(SELECT...)))
.如果找到,则将"正在进行"状态分配给该AdjustedStatus
字段,否则AdjustedStatus
从(未调整的)Status
值设置.
调整后的状态已经得出这样每个表中的行,GROUP BY
将AdjustedStatus
与MemberIdentifier
为了得到这两个字段值的所有独特的组合.然后将其制作为子查询 - 别名为subq
.然后聚合(GROUP BY
)AdjustedStatus
并计算出现次数,即MemberIdentifier
每次出现的唯一s数.
我假设您有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创建一条记录,其中包含所有可能的三种状态.然后,它根据总体状态对结果进行分组并输出计数.
查询的输出是
归档时间: |
|
查看次数: |
1202 次 |
最近记录: |