Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询-以更简单的方式重写_Sql_Sql Server - Fatal编程技术网

SQL查询-以更简单的方式重写

SQL查询-以更简单的方式重写,sql,sql-server,Sql,Sql Server,使用SQL Server 2016 我有下面的T-SQL查询,可以满足我的需要,但它包含大量重复。有没有办法用更优雅的方式重写它 SELECT z.* FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum, [new_state] AS [Last_State], DATEADD(M

使用SQL Server 2016

我有下面的T-SQL查询,可以满足我的需要,但它包含大量重复。有没有办法用更优雅的方式重写它

SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           DATEADD(MONTH, 0, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -1, @date)
) z
WHERE z.rowNum = 1
UNION
SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           DATEADD(MONTH, -1, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -2, @date)
) z
WHERE z.rowNum = 1
UNION
SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           DATEADD(MONTH, -2, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -3, @date)
) z
WHERE z.rowNum = 1;

etc....for 12 times
正如你所看到的,我将同一份声明改为一个月12次。 请告知。
注意。

很难测试脚本,但是您可以尝试以下方法:

SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id], DATEADD(MONTH,-1 * t.num, @date) ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           DATEADD(MONTH, t.num, @date) AS [date]
    FROM [dbo].[CR_hist_Data]
    CROSS JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)  )  t(num)
    WHERE [action_timestamp_formatted] < DATEADD(MONTH, -1 * t.num, @date)
) z
WHERE z.rowNum = 1
用例:

SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id], MONTH([action_timestamp] ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           CASE WHEN [action_timestamp_formatted] < DATEADD(MONTH, 1, @date) THEN DATEADD(MONTH, 0, @date)
                WHEN [action_timestamp_formatted] < DATEADD(MONTH, 2, @date) THEN DATEADD(MONTH, 1, @date)
                WHEN [action_timestamp_formatted] < DATEADD(MONTH, 3, @date) THEN DATEADD(MONTH, 2, @date) END AS [date]
    FROM [dbo].[CR_hist_Data]
) z
WHERE z.rowNum = 1

我认为使用公共表表达式可能会有所帮助

with dates(r, currmonth, lastmonth) as
(select 1 r, eomonth(@date) CurrMonth, eomonth(@date,-1) LastMonth
 union all
 select r+1, eomonth(@date,-1*r), eomonth(@date,-1*(r+1)) from dates
 where r < 12)

SELECT z.*
FROM
(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY [id],dates.r ORDER BY [action_timestamp] DESC) AS rowNum,
           [new_state] AS [Last_State],
           dates.currmonth AS [date]
    FROM [dbo].[CR_hist_Data]
    join dates on 1=1
    WHERE [action_timestamp_formatted] < dates.lastmonth
) z
WHERE z.rowNum = 1

在没有样本数据和预期输出的情况下,很难看到您正在做什么,但似乎可以使用and's ROWS子句来限制要应用聚合或函数的行。请添加样本记录和预期结果。也许还有其他方法可以解决这个问题,但是很难从这个查询中推断出您想要做什么,让我添加一些虚拟数据。感谢您对此进行调查,并同意您的意见。看起来是每个月的第一条记录吗?每个月的最后一条记录将不会返回相同的结果集,因为您有相同的分区子句,因此它将返回与第一条记录相同的数据。根据OP edit对tnumohh使用负数,他修改了问题