如何在SQL中显示这样的输出?

时间:2017-08-23 07:17:18

标签: sql count group-by sql-server-2014 tabular

我有一张如下所示的表格:

+----------------+-------+----------+---------+
| Name           | Model | system   | ItemTag |
+----------------+-------+----------+---------+
| Alarm Id       | T58   | ASC      |         |
+----------------+-------+----------+---------+
| Door Lock      | F48   | ASC      |         |
+----------------+-------+----------+---------+
| AlarmSounder   | T58   | ASC      |         |
+----------------+-------+----------+---------+
| Card Reader    | K12   | ASC      |         |
+----------------+-------+----------+---------+
| Magnetic Lock  | F48   | ASC      |         |
+----------------+-------+----------+---------+
| T2 Card Reader | K12   | ASC      |         |
+----------------+-------+----------+---------+
| Power   Supply | Null  | ASC      |         |
+----------------+-------+----------+---------+
| Battery         |  Null| ASC      |         |
+----------------+-------+----------+---------+

现在我想显示如下数据:

+-------------+-------+--------+--------+
| Name        | Model | system | count  |
+-------------+-------+--------+--------+
| Alarm       | T58   | ASC    | 2      |
+-------------+-------+--------+--------+
| Door Lock   | F58   | ASC    | 2      |
+-------------+-------+--------+--------+
| Card Reader | K12   | ASC    | 2      |
+-------------+-------+--------+--------+
|Power supply | Null   | ASC    | 1     |
+-------------+-------+--------+--------+
| Battery    | Null   | ASC    | 1     |
+-------------+-------+--------+--------+

如何在SQL中执行此操作?

更新 我还包括null列作为我的第二次更新。

3 个答案:

答案 0 :(得分:1)

您可以使用窗口函数:

SELECT Name, Model, system, cnt AS count 
FROM (SELECT *, COUNT(*) OVER(PARTITION BY Model) AS cnt,
            ROW_NUMBER() OVER(PARTITION BY Model ORDER BY ...) AS rn
      FROM your_tab) AS sub
WHERE rn = 1;

<强> Rextester Demo

请记住,您需要一个列进行排序,因此(id / timestamp)应该用于获取组中的第一个值。

修改

  

因为我有与null列相关的不同名称。我怎么能把它分开呢

SELECT Name, Model, system, cnt AS count 
FROM (SELECT *, COUNT(*) OVER(PARTITION BY Model) AS cnt,
            ROW_NUMBER() OVER(PARTITION BY Model ORDER BY id) AS rn
      FROM my_tab
      WHERE Model IS NOT NULL) AS sub
WHERE rn = 1
UNION ALL
SELECT Name, Model, system, 1
FROM my_tab
WHERE Model IS NULL;

<强> RextesterDemo 2

答案 1 :(得分:1)

您可以进行如下简单查询

SELECT MIN(Name) Name, 
       Model, 
       system, 
       COUNT(*) [count]
  FROM yourtable
 GROUP BY Model, system

结果

Name        Model   system  count
Door Lock   F58     ASC     2
Card Reader K12     ASC     2
Alarm Id    T58     ASC     2

答案 2 :(得分:1)

简化了lad2025的解决方案,在一个步骤中计算NULL和NOT NULL,并为NULL行添加一些逻辑:

SELECT Name, Model, system, 
   CASE WHEN Model IS NULL THEN 1 ELSE cnt END AS count 
FROM
 (
   SELECT *, 
      COUNT(*) OVER(PARTITION BY Model) AS cnt,
      ROW_NUMBER() OVER(PARTITION BY Model ORDER BY Name) AS rn
   FROM my_tab
 ) AS sub
WHERE rn = 1         -- one row per model 
   OR Model IS NULL; -- all rows for the NULL model