我正在通过自定义SQL查询连接到Tableau 上的Microsoft SQL Server。我有一个包含 3 个字段的表日期时间、标签名称、值,我想将"值"字段中的空值替换为每组 TagName 中的最后一个(根据日期时间值(非空值。
|---------------------|------------------|-----------------|
| DateTime | TagName | Value
|---------------------|------------------|-----------------
| 15.04.2019 16:51:30| A | 10
|---------------------|------------------|-----------------
| 15.04.2019 16:52:42| A | NULL
|---------------------|------------------|-----------------
| 15.04.2019 16:53:14| A | NULL
|---------------------|------------------|-----------------
| 15.04.2019 17:52:14| A | 15
|---------------------|------------------|-----------------
| 15.04.2019 16:51:30| B | NULL
|---------------------|------------------|-----------------
| 15.04.2019 16:52:42| B | NULL
|---------------------|------------------|-----------------
| 15.04.2019 16:53:14| B | NULL
|---------------------|------------------|-----------------
| 15.04.2019 17:52:14| B | 15
|---------------------|------------------|-----------------|
新表应如下所示:
|---------------------|------------------|-----------------|
| DateTime | Computer | Value
|---------------------|------------------|-----------------
| 15.04.2019 16:51:30| A | 10
|---------------------|------------------|-----------------
| 15.04.2019 16:52:42| A | 10
|---------------------|------------------|-----------------
| 15.04.2019 16:53:14| A | 10
|---------------------|------------------|-----------------
| 15.04.2019 17:52:14| A | 15
|---------------------|------------------|-----------------
| 15.04.2019 16:51:30| B | 0
|---------------------|------------------|-----------------
| 15.04.2019 16:52:42| B | 0
|---------------------|------------------|-----------------
| 15.04.2019 16:53:14| B | 0
|---------------------|------------------|-----------------
| 15.04.2019 17:52:14| B | 15
|---------------------|------------------|-----------------|
这已经是我尝试过的了,但它在不考虑 TagNames 值的情况下替换了 NULL 值(在此示例中只有一个 TagName(。
SELECT Computer, DateTime
, CASE
WHEN Value IS NULL
THEN
(SELECT TOP 1 Value
FROM History
WHERE DateTime<T.DateTime
AND TagName='RM02EL00CPT81.rEp'
AND DateTime >='2018-12-31 23:59:00'
AND wwRetrievalMode='Delta'
AND Value IS NOT NULL ORDER BY DateTime DESC
)
ELSE Value
END
AS ValueNEW
FROM History T
WHERE TagName='RM02EL00CPT81.rEp' AND DateTime >='2018-12-31 23:59:00' AND wwRetrievalMode='Delta'
我想通过添加OVER(PARTITION BY TagName)
来做几乎相同的事情,但它抛出了一个错误。(这是因为它不适用于SELECT TOP 1
。
"经典"的差距和岛屿问题。您可以使用窗口函数实现此目的,而无需 2 次扫描或三角形连接:
WITH VTE AS(
SELECT CONVERT(datetime, [DateTime],104) AS [DateTime],
TagName,
[Value]
FROM (VALUES ('15.04.2019 16:51:30','A',10 ),
('15.04.2019 16:52:42','A',NULL),
('15.04.2019 16:53:14','A',NULL),
('15.04.2019 17:52:14','A',15 ),
('15.04.2019 16:51:30','B',NULL),
('15.04.2019 16:52:42','B',NULL),
('15.04.2019 16:53:14','B',NULL),
('15.04.2019 17:52:14','B',15 )) V([DateTime],TagName,[Value])),
Grps AS(
SELECT [DateTime],
TagName,
[Value],
COUNT(CASE WHEN [Value] IS NOT NULL THEN 1 END) OVER (PARTITION BY TagName ORDER BY [DateTime]
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Grp
FROM VTE)
SELECT DateTime,
TagName,
ISNULL(MAX([Value]) OVER (PARTITION BY TagName, Grp),0) AS [Value]
FROM Grps
ORDER BY TagName, [DateTime]
试试这个
;WITH CTE([DateTime],TagName,Valu)
AS
(
SELECT '15.04.2019 16:51:30','A' , 10 UNION ALL
SELECT '15.04.2019 16:52:42','A' , NULL UNION ALL
SELECT '15.04.2019 16:53:14','A' , NULL UNION ALL
SELECT '15.04.2019 17:52:14','A' , 15 UNION ALL
SELECT '15.04.2019 16:51:30','B' , NULL UNION ALL
SELECT '15.04.2019 16:52:42','B' , NULL UNION ALL
SELECT '15.04.2019 16:53:14','B' , NULL UNION ALL
SELECT '15.04.2019 17:52:14','B' , 15
)
SELECT [DateTime],TagName As Computer,
ISNULL(CASE WHEN Valu IS NOT NULL
THEN Valu
ELSE
(
SELECT TOP 1 Valu FROM
CTE i
WHERE i.TagName = o.TagName
) END,0) As Valu
FROM CTE o
结果
DateTime Computer Valu
---------------------------------------------
15.04.2019 16:51:30 A 10
15.04.2019 16:52:42 A 10
15.04.2019 16:53:14 A 10
15.04.2019 17:52:14 A 15
15.04.2019 16:51:30 B 0
15.04.2019 16:52:42 B 0
15.04.2019 16:53:14 B 0
15.04.2019 17:52:14 B 15
因此,您正在尝试从 Wonderware Historian 检索数据。也许您不需要任何窗口和替换,因为 Historian 检索引擎应该能够为您提供所需的数据,而无需空值。试试这个:
select DateTime, TagName as Computer, Value
from History
where TagName in ('A', 'B') --put here the tagnames you want to retrieve
and DateTime > '2018-12-31'
AND wwRetrievalMode='Delta'
order by TagName, DateTime