我正在通过自定义SQL查询连接到Tableau上的Microsoft SQL Server。我有一个包含3个字段DateTime,TagName,Value的表,我想用每个TagName组中的最后一个(尊重DateTime值)非空值替换Value字段中的空值。
|---------------------|------------------|-----------------|
| 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
。)
答案 0 :(得分: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]
答案 1 :(得分:1)
尝试一下
;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
答案 2 :(得分:0)
因此,您正在尝试从Wonderware Historian检索数据。也许您不需要进行任何窗口化和替换操作,因为Historian检索引擎应该能够为您提供所需的数据而不会包含null。试试这个:
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