我无法获得购买了商品A和B的客户的数量。以下是我正在使用的数据示例。
Customer No | Item
___________________
1 A
1 B
2 B
3 A
4 A
4 B
5 B
6 A
我正在尝试统计购买了商品A和B的顾客数量。这是我到目前为止所尝试的。我得到以下结果项目A = 5,项目B = 3,项目A和B = 6。
Select
count (distinct case when ItemNo = 'A' then customerNo end) as [A],
count (distinct case when ItemNo = 'B' then customerNo end) as [B],
count (distinct case when (ItemNo = 'A' or ItemNo = 'B') then customerNo end) as [AandB]
from Items
这是我想要得到的结果:
Item | Count
A 4
B 4
A and B 2
有人可以指出正确的方向吗?谢谢!
答案 0 :(得分:2)
我认为您的预期结果可能是A = 4
和B = 4
。
您可以尝试使用UNION ALL
来获取A
,B
和A & B
的金额。
SELECT ItemNo,COUNT(distinct customerNo) Count
FROM Items
GROUP BY ItemNo
UNION ALL
SELECT 'A and B',count(*)
FROM (
SELECT COUNT(DISTINCT ItemNo) cnt
FROM Items tt
WHERE ItemNo IN ('A','B')
GROUP BY [CustomerNo]
HAVING COUNT(DISTINCT ItemNo) = 2
) t1
答案 1 :(得分:2)
这是另一种实现方法。
SQL Server有一个有用的运算符INTERSECT
,这正是您在这里所需要的-两套的相交(购买A
的人和购买B
的人)。
我认为它比使用HAVING
过滤器进行模糊分组更具可读性。
就性能而言,您应该在真实数据上尝试所有变体。
样本数据
DECLARE @T TABLE (CustomerNo int, Item varchar(50));
INSERT INTO @T (CustomerNo, Item) VALUES
(1, 'A'),
(1, 'B'),
(2, 'B'),
(3, 'A'),
(4, 'A'),
(4, 'B'),
(5, 'B'),
(6, 'A');
查询
SELECT
Item
,COUNT(DISTINCT CustomerNo) AS CustomerCount
,0 AS SortOrder
FROM @T
GROUP BY Item
UNION ALL
SELECT
'A & B' AS Item
,COUNT(*) AS CustomerCount
,1 AS SortOrder
FROM
(
SELECT CustomerNo
FROM @T
WHERE Item = 'A'
INTERSECT
SELECT CustomerNo
FROM @T
WHERE Item = 'B'
) AS T
ORDER BY SortOrder, Item
;
查询的第一部分通过按Item
对客户进行简单分组来对客户进行计数。
查询的第二部分(在UNION ALL
之后)计算同时购买了A
和B
的那些客户。
SortOrder
列只是为了适当地排序最终结果。
结果
+-------+---------------+-----------+
| Item | CustomerCount | SortOrder |
+-------+---------------+-----------+
| A | 4 | 0 |
| B | 4 | 0 |
| A & B | 2 | 1 |
+-------+---------------+-----------+
答案 2 :(得分:1)
$($('.slides div')[++cur, cur%=max]).fadeIn(500);
您需要一个“ AND”,而不是在最后一个COUNT中使用“ OR”条件。在这里,我使用相关子查询来计算同一客户(I.customerNo = I2.customerNo)订购itemno'B'(I2.itemno ='B')的行数。如果计数> 0,则客户订购了商品A和B。
相关的子查询由I.customerNo = I2.customerNo条件建立。
这是一种较长的方法,即使您无法在COUNT中执行子查询,该方法也可以使用
select count (distinct case when I.ItemNo = 'A' then customerNo end) as A,
count (distinct case when I.ItemNo = 'B' then customerNo end) as B,
count (distinct case when (I.ItemNo = 'A' and (select count(*) from items as I2 where I2.itemno = 'B' and I.customerNo = I2.customerNo ) > 0)
then customerNo end) as AB
from Items as I;
答案 3 :(得分:0)
这是一种方法。我们可以先尝试按客户进行汇总以生成A和B计数。然后,汇总这些计数。
WITH cte AS (
SELECT customerNo,
COUNT(CASE WHEN Item = 'A' THEN 1 END) AS a_cnt,
COUNT(CASE WHEN Item = 'B' THEN 1 END) AS b_cnt
FROM Items
GROUP BY customerNo
)
SELECT 'A' AS Item, COUNT(CASE WHEN a_cnt > 0 THEN 1 END) AS Count, 0 AS pos FROM cte
UNION ALL
SELECT 'B', COUNT(CASE WHEN b_cnt > 0 THEN 1 END), 1 FROM cte
UNION ALL
SELECT 'A and B', COUNT(CASE WHEN a_cnt > 0 AND b_cnt > 0 THEN 1 END), 2 FROM cte
ORDER BY pos;
答案 4 :(得分:0)
我将通过两个聚合级别来做到这一点:
select sum(has_a) as num_A,
sum(has_b) as num_B,
sum(has_a * has_b) as num_AB
from (select i.customer,
max(case when item_no = 'A' then 1 else 0 end) as has_A,
max(case when item_no = 'B' then 1 else 0 end) as has_B
from items
group by i.customer
) ic;
您还可以在不同的行上获取此信息:
select has_a, has_b, count(*)
from (select i.customer,
max(case when item_no = 'A' then 1 else 0 end) as has_A,
max(case when item_no = 'B' then 1 else 0 end) as has_B
from items
group by i.customer
) ic
group by has_A, has_B;
这并不完全相同,因为这些值仅用于 产品组合。换句话说,每个客户只计算一次。我喜欢的是: