我有以下语句,该语句用于获取特定DDI的最新数据行。我现在想做的是用一长串的替换列表替换where语句中的单个DDI,但每个DDI仍然只有最新的一行。我非常确定我需要使用OVER和PARTITION BY来为每个DDI获取一个单独的窗口,但是即使阅读了Microsoft文档和更简化的教程,我仍然无法获得正确的语法。我怀疑我只需要朝正确的方向轻推即可。有人可以帮忙吗?
http://www.sqltutorial.org/sql-window-functions/sql-partition-by/
SELECT TOP 1
[Start Time]
,[Agent Name]
,[Reference]
,[charged op. (sec)]
,[Type]
,[Activation ID] as [actid]
FROM [iPR].[dbo].[InboundCallsView]
Where [type] = 'Normal operator call'
AND [DDI] = @DDI
Order By [Start Time] Desc
答案 0 :(得分:2)
不知道如何计划处理DDI的多个值,但这可能是一个问题。最好的方法是使用表值参数。如果传入定界列表,则也必须拆分字符串,这不是处理此类问题的好方法。
此查询将为每个DDI返回最新的查询。
SELECT
[Start Time]
, [Agent Name]
, [Reference]
, [charged op. (sec)]
, [Type]
, [actid]
from
(
SELECT
[Start Time]
, [Agent Name]
, [Reference]
, [charged op. (sec)]
, [Type]
, [actid]
, RowNum = ROW_NUMBER() over(partition by DDI order by [Start Time] desc)
FROM [iPR].[dbo].[InboundCallsView]
where [type] = 'Normal operator call'
--and [DDI] = @DDI
) x
where x.RowNum = 1
答案 1 :(得分:1)
因此,让我们假设一个包含此数据的表(注意我如何清除列名以删除空格,特殊字符等):
x == (int)(double)x;
正如您所说,您可以使用窗口函数来获取所需的内容。但是,让我向您展示不需要首先使用窗口函数的方法。
您要记录+---+------------------+--------+------+----+------+---+
| 1 | 2019-03-28 08:00 | agent1 | foo1 | 60 | foo1 | 1 |
+---+------------------+--------+------+----+------+---+
| 1 | 2019-03-28 09:00 | agent2 | foo2 | 70 | foo2 | 2 |
| 2 | 2019-03-27 08:00 | agent3 | foo3 | 80 | foo3 | 3 |
| 2 | 2019-03-27 09:00 | agent4 | foo4 | 90 | foo4 | 4 |
+---+------------------+--------+------+----+------+---+
是该DDI的最大值的位置。您可以使用以下查询获取每个DDI的最大值StartTime
:
StartTime
然后,您可以将该查询加入基本表/视图中,以获取所需的记录。使用中间CTE,您可以执行以下操作:
SELECT
ddi,
max_start = MAX(StartTime)
FROM InboundCallsView
GROUP BY ddi
现在,如果您真的想使用WINDOW函数,则可以使用WITH
ddiWithMaxStart AS
(
SELECT
ddi,
max_start = MAX(StartTime)
FROM InboundCallsView
GROUP BY ddi
)
SELECT InboundCallsView.*
FROM InboundCallsView
INNER JOIN ddiWithMaxStart ON
ddiWithMaxStart.ddi = InboundCallsView.ddi
AND ddiWithMaxStart.max_start = InboundCallsView.StartTime
获得类似的效果:
ROW_NUMBER
请注意,使用此方法,您无需将基本视图/表连接到中间CTE。
您可以测试每种方法的性能,以查看哪种方法最适合您。