将值列表应用于where子句时替代游标?

时间:2016-10-05 19:29:28

标签: sql-server tsql

除了获取9月的所有日期之外,还有另外一种方法可以获得不同的日期:

9/1/2016
9/2/2016
9/3/2016

并将每个值应用于查询。说出类似的话:

Select GuitarId,GuitarBrand
From GuitarSales
Where GuitarDate = @date

我不想使用光标,是否可以选择这样做?

我尝试了CTE,但即便如此,我也必须为每个日期应用光标。

3 个答案:

答案 0 :(得分:4)

如果您想要一个月的所有日期,可以使用

Select GuitarId,GuitarBrand
From GuitarSales
Where month(GuitarDate) = 9
and year(GuitarDate) = 2016;

答案 1 :(得分:2)

如果我理解正确,您需要一份9月份所有日期的清单。这是一个快速解决方案,可以获得9月份所有日子的无间隙列表:在您的查询中,您可以将其用作来源和LEFT JOIN您的实际数据。

WITH RunningNumbers AS
(
    SELECT TOP(30) ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 AS Nr
    FROM sys.objects 
)
SELECT {d'2016-09-01'}+Nr AS RunningDate
FROM RunningNumbers

有许多示例,如何动态创建计数表。可以从任何有足够行的表中轻松地获取小数字(在本例中为30)。

如果您更频繁地需要这个,您可能会想到 Numbers-Table

答案 2 :(得分:0)

假设你有一个关于GuitarDate的索引,你可以通过这种方式在谓词中创建一个SARGable,这样你仍然可以利用索引搜索的速度。

declare @date datetime = '2016-09-10' --just to demonstrate starting with September 10, 2016

select gs.GuitarId
    , gs.GuitarBrand
From GuitarSales gs
where gs.GuitarDate >= dateadd(month, datediff(month, 0, @date), 0) --beginning of the month for @date
    and gs.GuitarDate < dateadd(month, datediff(month, 0, @date) + 1, 0) --beginning of next month