Answers:
您可以将CASE
语句与聚合函数一起使用。这与PIVOT
某些RDBMS中的函数基本相同:
SELECT distributor_id,
count(*) AS total,
sum(case when level = 'exec' then 1 else 0 end) AS ExecCount,
sum(case when level = 'personal' then 1 else 0 end) AS PersonalCount
FROM yourtable
GROUP BY distributor_id
COUNT
将计数distributor_id
明智。不是表格的所有行,对不对?
一种肯定有效的方法
SELECT a.distributor_id,
(SELECT COUNT(*) FROM myTable WHERE level='personal' and distributor_id = a.distributor_id) as PersonalCount,
(SELECT COUNT(*) FROM myTable WHERE level='exec' and distributor_id = a.distributor_id) as ExecCount,
(SELECT COUNT(*) FROM myTable WHERE distributor_id = a.distributor_id) as TotalCount
FROM (SELECT DISTINCT distributor_id FROM myTable) a ;
编辑:
请参阅@KevinBalmforth的性能细分,以了解为什么您可能不想使用此方法,而应该选择@ Taryn♦的答案。我离开这是为了让人们可以理解他们的选择。
sum(case...)
则应考虑解决方案。
group by
以count(*)
@Mihai所示的简单替换整个嵌套查询的好处-进一步简化了MySQL语法。
SELECT
distributor_id,
COUNT(*) AS TOTAL,
COUNT(IF(level='exec',1,null)),
COUNT(IF(level='personal',1,null))
FROM sometable;
COUNT
仅计算non null
值,并且仅在满足条件时DECODE
才会返回非null值1
。
distributor_id
将查询节目?总共显示1行。
以其他发布的答案为基础。
两者都会产生正确的值:
select distributor_id,
count(*) total,
sum(case when level = 'exec' then 1 else 0 end) ExecCount,
sum(case when level = 'personal' then 1 else 0 end) PersonalCount
from yourtable
group by distributor_id
SELECT a.distributor_id,
(SELECT COUNT(*) FROM myTable WHERE level='personal' and distributor_id = a.distributor_id) as PersonalCount,
(SELECT COUNT(*) FROM myTable WHERE level='exec' and distributor_id = a.distributor_id) as ExecCount,
(SELECT COUNT(*) FROM myTable WHERE distributor_id = a.distributor_id) as TotalCount
FROM myTable a ;
但是,性能却大不相同,随着数据量的增长,这显然将更加相关。
我发现,假设在表上未定义索引,则使用SUM的查询将执行单个表扫描,而使用COUNTs的查询将进行多个表扫描。
例如,运行以下脚本:
IF OBJECT_ID (N't1', N'U') IS NOT NULL
drop table t1
create table t1 (f1 int)
insert into t1 values (1)
insert into t1 values (1)
insert into t1 values (2)
insert into t1 values (2)
insert into t1 values (2)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (3)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
insert into t1 values (4)
SELECT SUM(CASE WHEN f1 = 1 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 2 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 3 THEN 1 else 0 end),
SUM(CASE WHEN f1 = 4 THEN 1 else 0 end)
from t1
SELECT
(select COUNT(*) from t1 where f1 = 1),
(select COUNT(*) from t1 where f1 = 2),
(select COUNT(*) from t1 where f1 = 3),
(select COUNT(*) from t1 where f1 = 4)
突出显示2条SELECT语句,然后单击“显示估计的执行计划”图标。您将看到第一个语句将执行一个表扫描,第二个语句将执行4。显然,一个表扫描比4好。
添加聚簇索引也很有趣。例如
Create clustered index t1f1 on t1(f1);
Update Statistics t1;
上面的第一个SELECT将执行单个聚集索引扫描。第二个SELECT将执行4个聚集索引查找,但是它们仍然比单个聚集索引扫描昂贵。我在具有800万行的表上尝试了相同的操作,而第二个SELECT仍然昂贵得多。
对于MySQL,可以缩短为:
SELECT distributor_id,
COUNT(*) total,
SUM(level = 'exec') ExecCount,
SUM(level = 'personal') PersonalCount
FROM yourtable
GROUP BY distributor_id
好吧,如果必须在一个查询中全部包含所有内容,则可以进行并集:
SELECT distributor_id, COUNT() FROM ... UNION
SELECT COUNT() AS EXEC_COUNT FROM ... WHERE level = 'exec' UNION
SELECT COUNT(*) AS PERSONAL_COUNT FROM ... WHERE level = 'personal';
或者,如果可以在处理后执行以下操作:
SELECT distributor_id, COUNT(*) FROM ... GROUP BY level;
您将获得每个级别的计数,并且需要将它们加起来以获得总数。
UNION
在生成包含COUNT(*)
函数多个实例的报告时非常有帮助。
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') FROM distributors UNION SELECT COUNT() AS EXEC_COUNT FROM distributors WHERE ' at line 1
。
我做这样的事情,我只给每个表一个字符串名称以在A列中标识它,并为列计数。然后我将它们全部合并,以便它们堆叠。我认为结果很不错-不确定与其他选项相比效率如何,但它满足了我的需求。
select 'table1', count (*) from table1
union select 'table2', count (*) from table2
union select 'table3', count (*) from table3
union select 'table4', count (*) from table4
union select 'table5', count (*) from table5
union select 'table6', count (*) from table6
union select 'table7', count (*) from table7;
结果:
-------------------
| String | Count |
-------------------
| table1 | 123 |
| table2 | 234 |
| table3 | 345 |
| table4 | 456 |
| table5 | 567 |
-------------------
a query that I created makes ...
-那查询在哪里?
我认为这也可以为您服务 select count(*) as anc,(select count(*) from Patient where sex='F')as patientF,(select count(*) from Patient where sex='M') as patientM from anc
您也可以选择和计算相关表格,例如 select count(*) as anc,(select count(*) from Patient where Patient.Id=anc.PatientId)as patientF,(select count(*) from Patient where sex='M') as patientM from anc
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'