我有下表:
UID | ID | Type
1 | 1 | product
1 | 2 | product
1 | 3 | service
1 | 4 | product
1 | 5 | product
2 | 6 | service
1 | 7 | order
2 | 8 | invoice
2 | 9 | product
我想最终:
UID | product | service | invoice | order
1 | 4 | 1 | 0 | 1
2 | 1 | 1 | 1 | 0
SQL查询会是什么样的?或者至少是最充足的一个?
答案 0 :(得分:7)
如果您真的只需要这四种类型,那么您可以按如下方式对值进行硬编码:
select UID,
count(case when type='product' then 1 else null end) as product,
count(case when type='service' then 1 else null end) as service,
count(case when type='invoice' then 1 else null end) as invoice,
count(case when type='order' then 1 else null end) as order
from MyTable
group by UID
order by UID
答案 1 :(得分:7)
您要做的是一个数据透视操作,SQL语法不直接支持它。但是,它并不太复杂,概念上涉及两个步骤:
我正在使用此数据集作为示例:
mysql> select * from foo;
+------+------+---------+
| uid | id | type |
+------+------+---------+
| 1 | 1 | product |
| 1 | 2 | product |
| 1 | 3 | service |
| 1 | 4 | product |
| 1 | 5 | product |
| 2 | 6 | service |
| 1 | 7 | order |
| 2 | 8 | invoice |
| 2 | 9 | product |
+------+------+---------+
第1步是“炸毁”数据集:
select uid
, case when type = 'product' then 1 else 0 end as is_product
, case when type = 'service' then 1 else 0 end as is_service
, case when type = 'invoice' then 1 else 0 end as is_invoice
, case when type = 'order' then 1 else 0 end as is_order
from foo;
给出:
+------+------------+------------+------------+----------+
| uid | is_product | is_service | is_invoice | is_order |
+------+------------+------------+------------+----------+
| 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 |
| 2 | 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 |
| 2 | 0 | 0 | 1 | 0 |
| 2 | 1 | 0 | 0 | 0 |
+------+------------+------------+------------+----------+
接下来,我们在每个日期的输出中折叠为一行,并将每个is_ *列相加,使用或初始查询作为内联视图(也称为“子查询”):
select uid
, sum(is_product) as count_product
, sum(is_service) as count_service
, sum(is_invoice) as count_invoice
, sum(is_order) as count_order
from (
select uid
, case when type = 'product' then 1 else 0 end as is_product
, case when type = 'service' then 1 else 0 end as is_service
, case when type = 'invoice' then 1 else 0 end as is_invoice
, case when type = 'order' then 1 else 0 end as is_order
from foo
) x
group by uid;
(另请注意,您可以将这两个查询合并为一个,但为了清楚起见,我在这里单独显示它们;至少在MySQL中,这似乎导致更简单的执行计划,这通常意味着更快的执行 - 如总是,在真实的数据集上测试你的SQL性能,不要相信我的话!)
这给了我们:
+------+---------------+---------------+---------------+-------------+
| uid | count_product | count_service | count_invoice | count_order |
+------+---------------+---------------+---------------+-------------+
| 1 | 4 | 1 | 0 | 1 |
| 2 | 1 | 1 | 1 | 0 |
+------+---------------+---------------+---------------+-------------+
这是期望的结果。
答案 2 :(得分:2)
您必须在MySQL中使用CASE statements将行数据转换为列(反之亦然):
SELECT t.uid,
SUM(CASE WHEN t.type = 'product' THEN COUNT(*) END) as PRODUCT,
SUM(CASE WHEN t.type = 'service' THEN COUNT(*) END) as SERVICE,
SUM(CASE WHEN t.type = 'invoice' THEN COUNT(*) END) as INVOICE,
SUM(CASE WHEN t.type = 'order' THEN COUNT(*) END) as ORDER
FROM TABLE t
GROUP BY t.uid, t.type
答案 3 :(得分:1)
你正在寻找一种称为“数据透视表”的东西,这不是MySQL本身可以做的事情。
在这种情况下,您可能最好转换应用程序中的数据,并使用GROUP BY和/或DISTINCT的某种组合来收集您正在寻找的数据。这个查询可能有效,我还没有测试过:
SELECT Type, COUNT(ID), UID
FROM tablename
GROUP BY UID, Type
答案 4 :(得分:-3)
从mytable中选择计数(产品,服务,发票,订单)