我有一个表,该表具有按帐户关联的每个设备的数据:
account_id | model
1 | iPhone
1 | Samsung
2 | iPhone
3 | Samsung
4 | iPhone
4 | Samsung
4 | LG
我正在尝试创建一个查询,在其中我收集属于以下存储桶之一的帐户ID:仅iPhone ,三星 或iPhone和Samsung 。
在此示例中,他们希望帐户ID#4落入iPhone和Samsung的存储桶中。
到目前为止,我的结果产生了重叠,这将导致查询问题。
任何有关如何构造查询以产生这些结果的帮助都会有所帮助
谢谢你, 丹妮尔
答案 0 :(得分:0)
使用条件聚合
select account_id
from tables
group by account_id
having count(distinct model)=1
答案 1 :(得分:0)
此解决方案假定您的DBMS支持窗口功能。如果不是这种情况,请标记您的DBMS。会更加复杂。
SELECT TD1.*,
CASE WHEN MAX(CASE WHEN model = 'Samsung' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 1
AND MAX(CASE WHEN model <> 'Samsung' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 0 THEN 'Samsung Only'
WHEN MAX(CASE WHEN model = 'iPhone' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 1
AND MAX(CASE WHEN model <> 'iPhone' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 0 THEN 'iPhone Only'
WHEN MAX(CASE WHEN model = 'iPhone' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 1
AND MAX(CASE WHEN model = 'Samsung' THEN 1 ELSE 0 END) OVER
( PARTITION BY account_id) = 1 THEN 'iPhone and Samsung'
ELSE 'Other'
END AS Product_Tag
FROM TEST_DATA;
编辑:如果您的DBMS支持CTE,那也不错...
WITH TAGGED
( SELECT Account_ID,
SUM(CASE WHEN model = 'Samsung' THEN 1 ELSE 0 END) AS Samsung_Count,
SUM(CASE WHEN model = 'iPhone' THEN 1 ELSE 0 END) AS iPhone_Count,
SUM(CASE WHEN model NOT IN ('iPhone','Samsung') THEN 1 ELSE 0 END) AS Neither_Count
FROM (SELECT DISTINCT Account_ID,
model
FROM TEST_DATA
) TMP
GROUP
BY Account_ID
)
SELECT TD1.*,
'Samsung Only'
FROM TEST_DATA TD1
WHERE EXISTS
( SELECT 1
FROM Tagged
WHERE Samsung_Count = 1
AND iPhone_Count = 0
AND Neither_Count = 0
AND Tagged.account_id = TD1.account_id
)
UNION
SELECT TD1.*,
'iPhone Only'
FROM TEST_DATA TD1
WHERE EXISTS
( SELECT 1
FROM Tagged
WHERE Samsung_Count = 0
AND iPhone_Count = 1
AND Neither_Count = 0
AND Tagged.account_id = TD1.account_id
)
UNION
SELECT TD1.*,
'iPhone and Samsung Only'
FROM TEST_DATA TD1
WHERE EXISTS
( SELECT 1
FROM Tagged
WHERE Samsung_Count = 1
AND iPhone_Count = 1
AND Neither_Count = 0
AND Tagged.account_id = TD1.account_id
);
如果它都不支持...那不漂亮
SELECT TD1.*,
'Samsung Only'
FROM TEST_DATA TD1
WHERE TD1.model = 'Samsung'
AND NOT EXISTS
( SELECT 1
FROM TEST_DATA TD2
WHERE TD1.model <> TD2.model
)
UNION
SELECT TD1.*,
'iPhone Only'
FROM TEST_DATA TD1
WHERE TD1.model = 'iPhone'
AND NOT EXISTS
( SELECT 1
FROM TEST_DATA TD2
WHERE TD1.model <> TD2.model
)
UNION
SELECT TD1.*,
'Samsung and iPhone'
FROM TEST_DATA TD1
WHERE EXISTS
( SELECT 1
FROM (SELECT account_id,
SUM
( CASE WHEN model = 'iPhone' THEN 1
WHEN model = 'Samsung' THEN 1
ELSE 0
END
) AS product_agg
FROM (SELECT DISTINCT
account_id,
model
FROM TEST_DATA
) TMP
) TMP2
WHERE TMP2.product_agg = 2
AND TD1.account_id = TMP2.account_id
)
AND NOT EXISTS
( SELECT 1
FROM TEST_DATA TD2
WHERE TD2.model NOT IN ('iPhone','Samsung')
AND TD2.account_id = TD1.account_id
);
答案 2 :(得分:0)
执行GROUP BY
。在case
子句中使用HAVING
表达式来验证条件。
select account_id
from tablename
group by account_id
having count(case when model = 'iPhone' then 1 end) = count(*) -- #1 Only iPhones
or count(case when model = 'Samsung' then 1 end) = count(*) -- #2 Only Samsung
or count(distinct case when model in ('iPhone', 'Samsung') then model end) = 2 -- #3 both of them
说明:
1)-iPhone的数量与总数量相同,即仅iPhone。
2)-三星的数量与总数相同,即只有三星。
3)-不同的iPhone和三星的数量为2,即iPhone和三星。