如果未找到项目IN列表

时间:2016-04-21 18:52:43

标签: sql sql-server

我正在跑步 Microsoft SQL Server 2012 - 11.0.5058.0(X64)     Windows NT 6.3(Build 9600:)(Hypervisor)上的标准版(64位)。我们以1Hz的频率将传感器数据输入到该数据库中。每个测试都有可变数量的传感器,可以是任何类型。频道名称(ChName)将向用户描述它们是什么。

用户将从网络界面中选择TestID以及他们想要的ChName

我有一个像这样设置的表,但包含大约1500万行和~50个TestID:

Timestamp datetimeTestID intChName varchar(100)Value real

Timestamp | TestID | ChName | Value
13:52:12  | 1000   | A      | 23
13:52:12  | 1000   | B      | 2
13:52:12  | 1000   | C      | 150
13:52:13  | 1000   | A      | 25
13:52:13  | 1000   | C      | 147
13:52:13  | 1000   | B      | 1
13:52:14  | 1000   | A      | 24
13:52:14  | 1000   | B      | 4
13:52:14  | 1000   | C      | 151
13:52:15  | 1000   | B      | 8
13:52:15  | 1000   | C      | 153
13:52:16  | 1000   | B      | 3
13:52:16  | 1000   | C      | 149
13:52:17  | 1000   | C      | 152
13:52:17  | 1000   | A      | 27

我正在寻找一个查询,当搜索特定的TestID和特定的ChName时,它将返回逗号分隔的结果,其搜索顺序为NULL,用于未找到的。

例如,搜索TestID 1000和ChNames('A','B','C')将返回:

Timestamp  | Data
13:52:12   | 23,2,150
13:52:13   | 25,1,147
13:52:14   | 24,4,151
13:52:15   | NULL,8,153
13:52:16   | NULL,3,149
13:52:17   | 27,NULL,152

搜索TestID 1000和ChNames('B','C')将返回:

Timestamp  | Data
13:52:12   | 2,150
13:52:13   | 1,147
13:52:14   | 4,151
13:52:15   | 8,153
13:52:16   | 3,149
13:52:17   | NULL,152

我在PHP中实现了这一点,返回包含TestIDChName的所有行,但它很慢(返回~503,000行,在PHP中进行分组大约需要2分钟)。我相信表格可以更好地构建,但不幸的是我继承了设计,因此试图获得更有效的查询。

此数据的目的是将其拉出并导出到Excel,或者用户可以通过webapp对其进行绘图。用户可以选择所有数据或特定时间段。

请求所有数据时的查询如下所示,然后在PHP中我将它们分组,如果找不到则添加NULL。

SELECT Timestamp,ChName,Value FROM data_table WHERE TestID=1000 AND ChName IN ('A','B',C') ORDER BY Timestamp,ChName

1 个答案:

答案 0 :(得分:0)

我建议使用PIVOT并根据您要为其生成结果的ChName值列表动态构建查询:

SELECT TimeStamp, 
       COALESCE([A], 'NULL') + ',' + 
       COALESCE([B], 'NULL') + ',' + 
       COALESCE([C], 'NULL') AS Data
FROM
    (   SELECT TimeStamp, ChName, Value 
        FROM   data_table
        WHERE  TestID = 1000
        AND    ChName IN ('A',B',C')
    ) AS SourceTable
PIVOT
    (
        Max(Value)
        FOR ChName IN ([A], [B], [C])
    ) AS PivotTable;

我没有对此进行测试,因此可能会出现一些语法问题。