如何在SQL中使用子查询“使用”和“分组依据”

时间:2016-08-27 11:28:07

标签: sql sql-server database sql-server-2008

请帮我在查询中查找计数。我使用“having”和“group by”收到错误。

我已修改我的代码,如下所示,以查找类似的事件计数。我希望根据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');

3 个答案:

答案 0 :(得分:1)

您不能在子查询中选择多个语句。通常我们还必须在子查询中使用其父查询建立关系。

我假设您想要针对子查询中的用户提取事件数,如果是这样,您必须编写如下代码。

    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

答案 1 :(得分:1)

您正在寻找相关的子查询,而不是<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:background="#ecedf1"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="@dimen/_200sdp" /> <RelativeLayout android:id="@+id/viewPagerIndicator" android:layout_width="match_parent" android:layout_height="25dp" android:layout_marginTop="@dimen/_180sdp" android:gravity="center"> <LinearLayout android:id="@+id/viewPagerCountDots" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:gravity="center" android:orientation="horizontal" /> </RelativeLayout> <com.information.aanjana.aanjanainformation.NonScrollGridView android:id="@+id/gv_android" android:layout_width="@dimen/_299sdp" android:layout_height="match_parent" android:horizontalSpacing="8dp" android:layout_centerHorizontal="true" android:numColumns="2" android:paddingLeft="@dimen/_4sdp" android:paddingRight="@dimen/_4sdp" android:layout_marginTop="@dimen/_220sdp" android:verticalSpacing="8dp"/> </RelativeLayout> </ScrollView> <!-- Here we add the layout outside the ScrollView --> <RelativeLayout android:layout_width="match_parent" android:layout_height="@dimen/_200sdp" android:gravity="top"> <!-- GRAVITY ADJUST --> <EditText android:layout_width="@dimen/_280sdp" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/_10sdp" android:layout_height="@dimen/_40sdp" android:text="fdgsdfhsfhsfghhsfhsfhf" android:background="@drawable/customedittext"/> </RelativeLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_height="match_parent" android:layout_width="@dimen/_170sdp" android:layout_gravity="start" app:menu="@menu/drawer" /> </android.support.v4.widget.DrawerLayout> 。但是,您的查询还有其他改进:

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()中删除,以简化逻辑。

答案 2 :(得分:0)

试试这个:

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