[英]How to use “Having” and “Group By” using subqueries in SQL
請幫助在我的查詢中找到計數。 使用“具有”和“分組依據”時出現錯誤。
我已如下修改我的代碼以查找類似的事件計數。 我正在尋找基於2個字段(user_id,item_id)的計數
SELECT
i.usr_id,
COUNT(DISTINCT CASE WHEN inc_data.Rep3 = 'y' THEN 1 END) AS RespBreach,
COUNT(DISTINCT CASE WHEN inc_data.Res3 = 'y' THEN 1 END) AS ResBreach,
COUNT(DISTINCT i.incident_id) as CallCount,
SUM(CASE WHEN act1.act_type= 'TRAVEL' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Travel_Time,
SUM(CASE WHEN act1.act_type= 'REMOTE' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Remote_Time,
(SELECT
COUNT(inc.incident_id) AS similar_inc_count,
inc.item_id, inc.cust_id
FROM
incident inc
GROUP BY
inc.usr_id, inc.item_id
HAVING
(COUNT(inc.incident_id) > 1)) AS similar_Call
FROM
incidents AS i
INNER JOIN
inc_data ON i.incident_id = inc_data.incident_id
INNER JOIN
actions act1 ON i.incident_id = act1.incident_id
WHERE
i.date_logged BETWEEN '2016-08-20' AND '2016-08-23'
GROUP BY
i.usr_id
預期結果:
| user_id | RespBreach | ResBreach | CallCount | Travel_Time | Remote_Time | Similer_call |
+---------+------------+-----------+-----------+-------------+-------------+--------------+
| 111 | 1 | 1 | 2 | 140 | 50 | 0 |
| 190 | 1 | 0 | 2 | 75 | 60 | 1 |
+---------+------------+-----------+-----------+-------------+-------------+--------------+
樣本數據:
CREATE TABLE incidents (incident_id int,date_logged datetime,usr_id int,dept_id int,item_id int, cust_id int)
insert into incidents values
('1001', '8/20/2016', '190', '3', '800', '10'),
('1002', '8/21/2016', '111', '4', '810', '12'),
('1003', '8/22/2016', '190', '3', '800', '10'),
('1004', '8/23/2016', '111', '4', '822', '12')
Create TABLE actions ( act_id int, act_type varchar(50) , incident_id int, usr_id int ,date_actioned datetime, service_time money)
Insert into actions VALUES
('1', 'TRAVEL', 1001, 190, 8/20/2016, 20),
('2', 'ASSIGN', 1001, 2, 8/21/2016, 1),
('3', 'TRAVEL', 1001, 190 ,8/22/2016, 10),
('4', 'REMOTE', 1001, 190, 8/23/2016, 30),
('5', 'TRAVEL', 1002, 111, 8/21/2016, 40),
('6', 'ASSIGN', 1002, 2, 8/22/2016 ,1),
('7', 'REMOTE', 1002, 111, 8/23/2016, 30),
('8', 'TRAVEL', 1002, 111, 8/24/2016, 60),
('9', 'TRAVEL', 1003, 190, 8/22/2016, 45),
('10', 'ASSIGN', 1003, 2, 8/23/2016 ,1),
('11', 'REMOTE', 1003, 190 ,8/23/2016 ,10),
('12', 'REMOTE', 1003, 190 ,8/23/2016 ,20),
('13', 'ASSIGN', 1004, 2 ,8/23/2016 ,1),
('14', 'TRAVEL', 1004, 111, 8/23/2016, 20),
('15', 'TRAVEL', 1004, 111, 8/23/2016, 20),
('16', 'REMOTE', 1004, 111, 8/23/2016, 20)
CREATE TABLE inc_data (incident_id int,Rep1 char(1), Rep2 char(1), Rep3 char(1), Res1 char(1), Res2 char(1), Res3 char(1))
insert into inc_data values
(1001, 'y', 'y', 'y', 'y', 'y', 'n'),
(1002, 'n', 'n', 'n', 'n', 'n', 'n'),
(1003, 'y', 'y', 'n', 'n', 'n', 'n'),
(1004, 'y', 'y', 'y', 'y' , 'y', 'y');
您不能在子查詢中選擇多個語句。 通常,我們還必須在子查詢內部與其父查詢建立關系。
我假設您想拉出子查詢中針對用戶的事件數,如果要這樣做,則必須如下代碼。
SELECT i.usr_id,
COUNT(DISTINCT CASE WHEN inc_data.Rep3 = 'y' THEN 1 END) AS RespBreach,
COUNT(DISTINCT CASE WHEN inc_data.Res3 = 'y' THEN 1 END) AS ResBreach,
COUNT(DISTINCT i.incident_id) as CallCount,
SUM(CASE WHEN act1.act_type= 'TRAVEL' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Travel_Time,
SUM(CASE WHEN act1.act_type= 'REMOTE' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Remote_Time,
ISNULL((SELECT COUNT(inc.incident_id) -1
FROM incidents inc
WHERE inc.usr_id=i.usr_id
GROUP BY inc.usr_id,inc.item_id
HAVING COUNT(inc.incident_id) > 1
),0)AS similar_inc_count
FROM incidents as i
INNER JOIN inc_data ON i.incident_id= inc_data.incident_id
INNER JOIN actions act1 on i.incident_id=act1.incident_id
WHERE i.date_logged BETWEEN '2016-08-20' AND '2016-08-23'
GROUP BY i.usr_id
您正在尋找一個相關的子查詢,而不是一個group by
。 但是,您的查詢還有其他改進:
SELECT i.usr_id,
MAX(CASE WHEN id.Rep3 = 'y' THEN 1 ELSE 0 END) AS RespBreach,
MAX(CASE WHEN id.Res3 = 'y' THEN 1 ELSE 0 END) AS ResBreach,
COUNT(DISTINCT i.incident_id) as CallCount,
SUM(CASE WHEN a.act_type = 'TRAVEL'
THEN a.service_time
ELSE 0
END) AS Travel_Time,
SUM(CASE WHEN a.act_type = 'REMOTE'
THEN a.service_time
ELSE 0
END) AS Remote_Time,
(SELECT COUNT(*) AS similar_inc_count
FROM (SELECT inc.item_id
FROM incident inc
WHERE inc.cust_id = i.user_id
GROUP BY inc.item_id
HAVING COUNT(inc.incident_id) > 1)
) inc
) AS similar_Call
FROM incidents i INNER JOIN
inc_data id
ON i.incident_id = id.incident_id INNER JOIN
actions a
ON i.incident_id = a.incident_id
WHERE i.date_logged BETWEEN '2016-08-20' AND '2016-08-23'
GROUP BY i.usr_id;
筆記:
COUNT(DISTINCT)
已被MAX()
取代。 MAX()
更易於理解和更有效。 IFNULL()
已從SUM()
刪除,以簡化邏輯。 嘗試這個:
SELECT i.usr_id,
COUNT(DISTINCT CASE WHEN inc_data.Rep3 = 'y' THEN 1 END) AS RespBreach,
COUNT(DISTINCT CASE WHEN inc_data.Res3 = 'y' THEN 1 END) AS ResBreach,
COUNT(DISTINCT i.incident_id) as CallCount,
SUM(CASE WHEN act1.act_type= 'TRAVEL' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Travel_Time,
SUM(CASE WHEN act1.act_type= 'REMOTE' THEN ISNULL(act1.service_time, 0) ELSE 0 END) AS Remote_Time,
(SELECT COUNT(inc.incident_id)
FROM incidents inc
GROUP BY inc.usr_id, inc.item_id
HAVING COUNT(inc.incident_id) > 1) AS similar_Call
FROM incidents as i
INNER JOIN inc_data ON i.incident_id= inc_data.incident_id
INNER JOIN actions act1 on i.incident_id=act1.incident_id
WHERE i.date_logged BETWEEN '2016-08-20' AND '2016-08-23'
GROUP BY i.usr_id
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.