【问题标题】:SQL count and distinct querySQL 计数和不同的查询
【发布时间】:2016-02-26 21:46:04
【问题描述】:

我正在尝试构建一个可以同时计数和区分的查询。这是原始数据

Raw Data

+--------+---------+
| IntID  | ErrorID |
+--------+---------+
| ins001 |    1    |
| ins001 |    1    |
| ins001 |    2    |
| ins002 |    3    |
| ins002 |    5    |
| ins002 |    5    |
| ins003 |    4    |
| ins003 |    1    |
| ins003 |    1    |
+--------+---------+

我试图完成的是对每个不同仪器 ID 的每个错误 ID 进行计数,如下所示:

What is expected

+--------+-------------+-------------+-------------+-------------+-------------+
| IntID  | ErrorID=001 | ErrorID=002 | ErrorID=003 | ErrorID=004 | ErrorID=005 |
+--------+-------------+-------------+-------------+-------------+-------------+
| ins001 |      2      |      1      |      0      |      0      |      0      |
| ins002 |      0      |      0      |      1      |      0      |      2      |
| ins003 |      2      |      0      |      0      |      1      |      0      |
+--------+-------------+-------------+-------------+-------------+-------------+

非常感谢任何建议或帮助。提前致谢

【问题讨论】:

  • 你用的是什么数据库?
  • 这是一个支点。不是最漂亮的东西,也不总是可行的。 SQL 服务器?什么版本?这里有几个 sql server c-sharpcorner.com/UploadFile/8911c4/… 的例子
  • 有多少个不同的错误 ID?总是 5 个还是 100 个?
  • 为什么显示器必须是对面的?通常更容易在用户界面中更改方向并让数据库返回原始计数数据...例如使用 count(*) 和 group by。

标签: sql count distinct


【解决方案1】:

如果您提前知道一组有限的 ErrorID,这应该可以工作。

    select IntID, [1] as [ErrorID=001], [2] as [ErrorID=002], [3] as [ErrorID=003], [4] as [ErrorID=004], [5] as [ErrorID=005]
    from
    (select IntID, ErrorID, 1 as cnt
        from #YourTable) as t
    pivot
    (
        count(cnt)
        for ErrorID in ([1], [2], [3], [4], [5])
    ) as pvt

编辑

根据您的要求,如果您有大量错误,您可以动态构建查询。 Coalesce 有助于为任意数量的错误构建字符串。 (RIGHT 仅用于去除字符串中的第一个逗号)

    DECLARE @DisplayList    varchar(1000)
    DECLARE @SearchList     varchar(1000)
    DECLARE @sql            varchar(MAX)

    select @DisplayList = COALESCE(@DisplayList, '') + ',[' + cast(ErrorID as VARCHAR(100)) + '] as ' + ' [ErrorID=' + cast(ErrorID as VARCHAR(100)) + ']' from #YourErrorsTable
    select @SearchList = COALESCE(@SearchList, '') + ',[' + cast(ErrorID as VARCHAR(100)) + ']' from #YourErrorsTable

    set @sql = 'select IntID' + @DisplayList +'
        from
        (select IntID, ErrorID, 1 as cnt
            from #YourTable) as t
        pivot
        (
            count(cnt)
            for ErrorID in (' + RIGHT(@SearchList, LEN(@SearchList)-1) + ')
        ) as pvt'

    EXEC(@sql)

【讨论】:

  • 这是一个很好的起点。但我确实有大量的错误 ID。知道怎么走吗?谢谢
  • 嗨@HernandoSalas,如果这个或任何答案已经解决了您的问题,请点击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
【解决方案2】:

如果您使用的是 MySql 或 PostgreSQL,则可以使用 group by 而不是 distinct。

select InstrumentID, ErrorID, count (*)
from table
group by InstrumentID, ErrorID

【讨论】:

  • Group by 不会使数据按照他的图像显示的那样跨行。
  • 我知道,但我建议这样做,然后他可以在其他地方操作数据或使用此结果用结果填充另一个表
  • 这是否仅限于 MySQL 和 Postgres?
  • 不是真的,但我相信它肯定会在这两个上工作,因为我每天都在使用它们
【解决方案3】:

如果是少量的错误 ID,您可以执行以下操作。

SQL Fiddle

SELECT 
    Instrumentid
  , SUM(CASE WHEN ErrorID = 1 THEN 1 ELSE 0 END) AS ErrorID_001
  , SUM(CASE WHEN ErrorID = 2 THEN 1 ELSE 0 END) AS ErrorID_002
  , SUM(CASE WHEN ErrorID = 3 THEN 1 ELSE 0 END) AS ErrorID_003
  , SUM(CASE WHEN ErrorID = 4 THEN 1 ELSE 0 END) AS ErrorID_004
  , SUM(CASE WHEN ErrorID = 5 THEN 1 ELSE 0 END) AS ErrorID_005
FROM YourTable
GROUP BY instrumentid

【讨论】:

  • 这是一个很好的起点。但我确实有大量的错误 ID。知道怎么走吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2017-07-04
  • 2023-03-20
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多