我有一个接受以下参数的存储过程:
现在我的查询如下:
SELECT COL1, MyDate
FROM [dbo].[MyTable]
WHERE MONTH([MyDate]) >= @fromMonth
AND MONTH([MyDate]) <= @toMonth
AND YEAR([MyDate]) >= @fromYear
AND YEAR([MyDate]) <= @toYear
GROUP BY COL1, MyDate
但是如果我使用参数运行查询:
即使我有结果应该返回,我也没有结果。
答案 0 :(得分:4)
对于sql server版本2012+,您可以使用DATEFROMPARTS
和EOMONTH
:
DECLARE @FromDate datetime, @ToDate datetime
SELECT @FromDate = DATEFROMPARTS(@fromYear, @FromMonth, 1),
@ToDate = EOMONTH(DATEFROMPARTS(@ToYear, @ToMonth, 1)),
SELECT COL1, MyDate
FROM [dbo].[MyTable]
WHERE [MyDate] >= @FromDate
AND [MyDate] <= @ToDate
GROUP BY COL1, MyDate
对于2012年之前的版本,您可以通过一些数学和演员来构建日期:
DECLARE @FromDate datetime, @ToDate datetime
SELECT @FromDate = CAST(CAST(@FromYear * 10000 + @FromMonth * 100 + 1 as char(8)) as date),
@ToDate = DATEADD(MONTH, cast(CAST(@ToYear * 10000 + @ToMonth * 100 + 1 as char(8)) as date))
SELECT COL1, MyDate
FROM [dbo].[MyTable]
WHERE [MyDate] >= @FromDate
AND [MyDate] < @ToDate
GROUP BY COL1, MyDate
请注意使用DateAdd
获取@ToDate
之后的第一天并使用<
而不是<=
。
答案 1 :(得分:0)
因为你没有从你的桌子给我们一些样本数据,所以我自己创建了。
CREATE TABLE #Temp
(
MyCol VARCHAR(10)
, MyDate DATETIME
);
INSERT INTO #Temp
( MyCol, MyDate )
VALUES ( 'A', GETDATE() ),
( 'A', '2016-09-01' ),
( 'B', '2016-09-03' ),
( 'B', '2016-08-28' ),
( 'A', '2017-03-01' ),
( 'A', '2017-04-01' );
让我们取一个日期(2016-09-01
)并将其分解。
您的WHERE
子句有效地测试了第一行的以下条件。
9 >= 9
=&gt;真9 <= 3
=&gt;假2016 >= 2016
=&gt;真2016 <= 2017
=&gt;真因为您AND
- 所有这些条件,您都不会返回您想要的结果。
您需要将您的值评估为日期而不是数字,否则您将遇到这些问题。
你可以这样做:
DECLARE @ToDate AS DATE = CONVERT(DATE, CONVERT(VARCHAR, @toYear) + '-' + CONVERT(VARCHAR, @toMonth) + '-1');
DECLARE @FromDate AS DATE = CONVERT(DATE, CONVERT(VARCHAR, @fromYear) + '-' + CONVERT(VARCHAR, @fromMonth) + '-1');
SELECT t.MyCol
, t.MyDate
FROM #Temp AS t
WHERE t.MyDate BETWEEN @FromDate AND @ToDate
GROUP BY t.MyCol
, t.MyDate;
这是一个很好的起点,但鉴于您提供的变量,您只能从2016-09-01
到2017-04-01
而非2016-09-01
到2017-03-31
获取数据。
所以你需要再增加一个月。您可以通过多种方式执行此操作(在月份中添加一个,然后检查它是否超过13,DATEADD
等。)
我之所以选择DATEADD
是因为它有点简单。
你的最终结果如下:
DECLARE @ToDate AS DATE = DATEADD(MONTH, 1, CONVERT(DATE, CONVERT(VARCHAR, @toYear) + '-' + CONVERT(VARCHAR, @toMonth) + '-1'));
DECLARE @FromDate AS DATE = CONVERT(DATE, CONVERT(VARCHAR, @fromYear) + '-' + CONVERT(VARCHAR, @fromMonth) + '-1');
SELECT t.MyCol
, t.MyDate
FROM #Temp AS t
WHERE t.MyDate >= @FromDate AND
t.MyDate < @ToDate
GROUP BY t.MyCol
, t.MyDate;
编辑:生成日期可能比做连接和转换更简洁。