繁体   English   中英

如何使用count来表示另一个表中的值

[英]How use count for value from another table

如何使用count连接不同的表。 请看看我的疑问。 我在这里使用CROSS APPLY。 但我没有得到实际的结果。 我如何从项目表中获取所有项目而不是在事件表中。

表格:Inc_cat

+------------+--------------+--+
| inc_cat_id |  inc_cat_n   |  |
+------------+--------------+--+
|          1 | Support      |  |
|          2 | PM           |  |
|          3 | Installation |  |
+------------+--------------+--+

表:事件

+-------------+---------+------------+-----------------+
| incident_id | item_id | inc_cat_id | date_logged     |
+-------------+---------+------------+-----------------+
|         100 |     555 |          1 |  2016-01-01     |
|         101 |     555 |          2 |  2016-01-18     |
|         103 |     444 |          3 |  2016-02-10     |
|         104 |     444 |          2 |  2016-04-01     |
|         105 |     666 |          1 |  2016-04-09     |
|         106 |     555 |          2 |  2016-04-20     |
+-------------+---------+------------+-----------------+

表:项目

+---------+---------+--+
| item_id | cust_id |  |
+---------+---------+--+
|     444 |      34 |  |
|     555 |      34 |  |
|     666 |      76 |  |
|     333 |      34 |  |
|     222 |      34 |  |
|     111 |      34 |  |
+---------+---------+--+

结果:

+---------+----------------+-----------+---------------------+
| item_id | count(Support) | count(PM) | count(Installation) |
+---------+----------------+-----------+---------------------+
|     555 |              0 |         1 |                   0 |
|     444 |              0 |         1 |                   0 |
|     666 |              0 |         0 |                   0 |
|     333 |              0 |         0 |                   0 |
|     222 |              0 |         0 |                   0 |
|     111 |              0 |         0 |                   0 |
+---------+----------------+-----------+---------------------+

我的查询:

 SELECT i.item_ID, 
 COUNT(CASE WHEN i.inc_cat_id = ic.inc_cat_id AND i.inc_cat_id = 1 THEN 1 END) AS cntSupport,
 COUNT(CASE WHEN i.inc_cat_id = ic.inc_cat_id AND i.inc_cat_id = 2 THEN 1 END) AS cntPM,
 COUNT(CASE WHEN i.inc_cat_id = ic.inc_cat_id AND i.inc_cat_id = 3 THEN 1 END) AS cntInstallation
 FROM @incident i
 CROSS APPLY @incCat ic
 WHERE (i.date_logged BETWEEN '2016-04-01' AND '2016-04-30')AND i.cust_id='34'
 GROUP BY i.item_ID

你不需要CROSS APPLY 一个简单的LEFT JOIN将:

SELECT i.item_id,
       COUNT(CASE WHEN inc.inc_cat_id = 1 THEN 1 END) AS cntSupport,
       COUNT(CASE WHEN inc.inc_cat_id = 2 THEN 1 END) AS cntPM,
       COUNT(CASE WHEN inc.inc_cat_id = 3 THEN 1 END) AS cntInstallation
FROM Item AS i
LEFT JOIN Incident AS inc ON i.item_id = inc.item_id AND
                      inc.date_logged BETWEEN '2016-04-01' AND '2016-04-30'        
WHERE i.cust_id = 34
GROUP BY i.item_id

您只需要从表Item开始,以便返回所有返回的项,如OP中的预期结果集。

在这里演示

除非我遗漏了什么,否则你的查询过于复杂:

SELECT item_ID, 
       COUNT(CASE WHEN .inc_cat_id = 1 THEN 1 END) AS cntSupport,
       COUNT(CASE WHEN inc_cat_id = 2 THEN 1 END) AS cntPM,
       COUNT(CASE WHEN inc_cat_id = 3 THEN 1 END) AS cntInstallation
  FROM @incident 
 GROUP BY item_ID

更新:

通过添加logged_date列,您只需要在ON子句中添加它。 您现在需要使用sp_executesql而不是EXEC来阻止sql注入:

DECLARE @fromDate DATE = '2016-04-01',
        @toDate DATE = '2016-04-30';

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql =
'SELECT
    i.item_id' + CHAR(10) +
(SELECT
'   , COUNT(CASE WHEN inc.inc_cat_id = ' + CONVERT(VARCHAR(10), inc_cat_id) + 
' THEN 1 END) AS ' + QUOTENAME('count(' + inc_cat_n + ')') + CHAR(10)
FROM #Inc_cat
ORDER BY inc_cat_id
FOR XML PATH('')
) +
'FROM #item AS i
LEFT JOIN #incident AS inc
    ON i.item_id = inc.item_id
    AND inc.date_logged BETWEEN @fromDate AND @toDate
GROUP BY i.item_id;';

PRINT (@sql);
EXEC sp_executesql
        @sql,
        N'@fromDate DATE, @toDate DATE',
        @fromDate,
        @toDate

在线演示


如果你只有3 Inc_cat ,那么Giorgos的答案是好的。 但是,如果您有未知数量的Inc_cat ,则需要动态执行此操作。 以下是使用动态交叉表的方法:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql =
'SELECT
    i.item_id' + CHAR(10) +
(SELECT
'   , COUNT(CASE WHEN inc.inc_cat_id = ' + CONVERT(VARCHAR(10), inc_cat_id) + 
' THEN 1 END) AS ' + QUOTENAME('count(' + inc_cat_n + ')') + CHAR(10)
FROM Inc_cat
ORDER BY inc_cat_id
FOR XML PATH('')
) +
'FROM Item AS i
LEFT JOIN Incident AS inc
    ON i.item_id = inc.item_id
GROUP BY i.item_id;';

PRINT (@sql);
EXEC (@sql);

在线演示

基本上,它只是Giorgos答案的动态版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM