2017-05-10 49 views
0

我有一張表,名爲theTable,我想從中導入一些數據。 theTable包含產品庫存值,我只關心在6個月內每個月的最後一天查找庫存餘額。SQL Server:WHERE子句只返回月份的最後一天範圍內的值

我有一個名爲DateKey的列,它看起來像yyyymmdd並描述了記錄股票餘額的日期。

舉個例子,我希望能夠推斷在DateKeystockValue20160131,20160331

爲此,我已經試過:

CREATE TABLE #theTable 
(
    DateKey INT, 
    stockValue INT 
); 

INSERT INTO #theTable 
VALUES (20160131, 4), (20160130, 5), 
     (20160312, 5), (20160331, 4); 

SELECT DateKey, stockValue 
FROM #theTable 
WHERE DateKey BETWEEN CONVERT(VARCHAR(8), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 16, 0), 112) 
        AND CONVERT(VARCHAR(8), DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 13, -1), 112) 

(其中我已經添加了convert()shenanigans以避免DateKey不是類型的錯誤DateTime

但是這(自然地)返回:

DateKey  stockValue 
20160131 4 
20160130 5 
20160312 5 
20160331 4 

我如何可以調整這條SQL語句,只包括:

DateKey  stockValue 
20160131 4 
20160331 4 

即月在我指定日期範圍內的最後幾天?

編輯

的問題是,如果有一種方法只拿到了最後一天的值,而不必硬編碼一個'WHERE DATEKEY IN(「20160131」,「20160228」,「20160331」)因爲我會選擇許多不同的值,這會使硬編碼解決方案變得非常容易出錯和耗時。

+2

爲什麼'datekey'不是'date'型擺在首位?由於看起來你只是在尋找本月的最後一天,你是否檢查過['EOMONTH()'](https://docs.microsoft.com/zh-cn/sql/t-sql/函數/ emonth-transact-sql)函數? – alroc

+0

[SQL Query查找月份的最後一天]的可能重複(http://stackoverflow.com/questions/16646585/sql-query-to-find-the-last-day-of-the-month) –

+0

快速谷歌搜索產生重複的頁面。你有沒有試圖自己解決這個問題? –

回答

2

使用EOMONTH函數,只得到這樣的行。

SELECT DateKey, stockValue 
FROM #theTable 
where CONVERT(date, convert(varchar(10), datekey)) = eomonth(CONVERT(date, convert(varchar(10), datekey))) 
+0

感謝您的回答。我早些時候提到了EOMONTH,但是我認爲我確實過時了實現,因爲某些原因,我發現使用DateTime類型的DateKey難以實現。但是這個解決方案真的很優雅。 – Cenderze

1

這給你當月的末尾:

FORMAT(EOMONTH(GETDATE()), 'yyyyMMdd') 

這給你一個月的2個月前結束:

FORMAT(EOMONTH(DATEADD(MONTH, -2, GETDATE())), 'yyyyMMdd') 
0
SELECT DateKey, stockValue 
FROM #theTable 
WHERE DateKey = 
DATEADD(month, ((YEAR(DateKey) - 1900) * 12) + MONTH(DateKey), -1) 
0

假設你不能保證最後一個datekey將是該月的最後一天

這將工作

create table #theTable(
DateKey int, 
stockValue int 
); 

insert into #theTable 
VALUES(20160131,4), 
(20160130,5), 
(20160312,5), 
(20160331,4); 

;with lastDayOfMonth as (
select 
max(DateKey) as MaxDate 
from #theTable 
group by left(cast(DateKey as varchar(8)),6)) 

SELECT DateKey, stockValue ,left(cast(DateKey as varchar(8)),6) 
FROM #theTable 
inner join lastDayOfMonth 
on MaxDate = DateKey 
WHERE DateKey between convert(varchar(8),DATEADD(month,datediff(month,0,getdate())-16,0),112) 
and CONVERT(VARCHAR(8),DATEADD(MONTH, DATEDIFF(month, -1, getdate())-13,-1),112) 

drop table #theTable 
0

您可以使用EOMONTH(),如下

select * from #thetable where 
convert(date,convert(varchar(8), DateKey,112)) = eomonth(convert(date, convert(varchar(8), datekey,112))) 

輸出:

+----------+------------+ 
| DateKey | stockValue | 
+----------+------------+ 
| 20160131 |   4 | 
| 20160331 |   4 | 
+----------+------------+ 
0

你可以利用EOMONTH(https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql)來檢查日期是本月的最後日期。

事情是這樣的:

create table #theTable(
DateKey int, 
stockValue int 
); 

insert into #theTable 
VALUES(20160131,4), 
(20160130,5), 
(20160312,5), 
(20160331,4); 


SELECT DateKey, stockValue 
FROM #theTable 
WHERE DateKey between convert(varchar(8),DATEADD(month,datediff(month,0,getdate())-16,0),112) 
and CONVERT(VARCHAR(8),DATEADD(MONTH, DATEDIFF(month, -1, getdate())-13,-1),112) 
AND EOMONTH (CONVERT(varchar(8),datekey)) = CONVERT(varchar(8),datekey) 


DROP TABLE #theTable