[SQL] 실종 날짜를 표시하는 SQL 서버
SQL실종 날짜를 표시하는 SQL 서버
SiteVisitID siteName visitDate
------------------------------------------------------
1 site1 01/03/2014
2 Site2 01/03/2014
3 site1 02/03/2014
4 site1 03/03/2014
5 site2 03/03/2014
6 site1 04/03/2014
7 site2 04/03/2014
8 site2 05/03/2014
9 site1 06/03/2014
10 site2 06/03/2014
11 site1 08/03/2014
12 site2 08/03/2014
13 site1 09/03/2014
14 site2 10/03/2014
이 개 사이트와 달의 일상에 대한 방문 항목이 각각 필요가 그래서 오늘 우리는 22 개 항목을 기대하고 2014년 11월 3일 것을 고려하고있다하지만 8 누락, SQL 우리의 모든 방법이 때문에 단지 14 항목이 있습니다 날짜 누락 된 항목을 꺼내 수
사이트에 대한 해당 월의 현재 날짜까지
siteName missingDate
-----------------------
site2 02/03/2014
site1 05/03/2014
site1 07/03/2014
site2 07/03/2014
site2 09/03/2014
site1 10/03/2014
site1 11/03/2014
site2 11/03/2014
여기에 내가 믿는 내 실패한 시도가 모두 논리적 구문이 잘못이다
select
siteName, visitDate
from
SiteVisit not in (SELECT siteName, visitDate
FROM SiteVisit
WHERE Day(visitDate) != Day(CURRENT_TIMESTAMP)
AND Month(visitDate) = Month(CURRENT_TIMESTAMP))
참고 : 실제 테이블의 상기 데이터 열을 간략화 버전
해결법
-
==============================
1.난 당신이 테이블 (이 바이올린에 그것을 밖으로 시도)로 당신이 선택한 날짜 사이의 모든 일을 얻을 수있는 테이블 반환 함수를 사용하는 것이 좋습니다 것입니다 :
난 당신이 테이블 (이 바이올린에 그것을 밖으로 시도)로 당신이 선택한 날짜 사이의 모든 일을 얻을 수있는 테이블 반환 함수를 사용하는 것이 좋습니다 것입니다 :
CREATE FUNCTION dbo.GetAllDaysInBetween(@FirstDay DATETIME, @LastDay DATETIME) RETURNS @retDays TABLE ( DayInBetween DATETIME ) AS BEGIN DECLARE @currentDay DATETIME SELECT @currentDay = @FirstDay WHILE @currentDay <= @LastDay BEGIN INSERT @retDays (DayInBetween) SELECT @currentDay SELECT @currentDay = DATEADD(DAY, 1, @currentDay) END RETURN END
(I 쉽게 CopyPaste에-시험에 대한 간단한 테이블 설정 포함)
CREATE TABLE SiteVisit (ID INT PRIMARY KEY IDENTITY(1,1), visitDate DATETIME, visitSite NVARCHAR(512)) INSERT INTO SiteVisit (visitDate, visitSite) SELECT '2014-03-11', 'site1' UNION SELECT '2014-03-12', 'site1' UNION SELECT '2014-03-15', 'site1' UNION SELECT '2014-03-18', 'site1' UNION SELECT '2014-03-18', 'site2'
당신이 이와 같은 "경계 일"알고있을 때 지금 당신은 단순히 어떤 방문이 발생하지 무슨 일 확인하실 수 있습니다 :
SELECT DayInBetween AS missingDate, 'site1' AS visitSite FROM dbo.GetAllDaysInBetween('2014-03-11', '2014-03-18') AS AllDaysInBetween WHERE NOT EXISTS (SELECT ID FROM SiteVisit WHERE visitDate = AllDaysInBetween.DayInBetween AND visitSite = 'site1')
아니면 모든 사이트에서이 쿼리를 사용할 수 있습니다 방문하지 않은 모든 일을 알고 싶은 경우 :
SELECT DayInBetween AS missingDate, Sites.visitSite FROM dbo.GetAllDaysInBetween('2014-03-11', '2014-03-18') AS AllDaysInBetween CROSS JOIN (SELECT DISTINCT visitSite FROM SiteVisit) AS Sites WHERE NOT EXISTS (SELECT ID FROM SiteVisit WHERE visitDate = AllDaysInBetween.DayInBetween AND visitSite = Sites.visitSite) ORDER BY visitSite
그냥 보조 노트에 : 당신이 사이트 이름 정말 별도의 테이블로 가야 만 SiteVisit에서 참조 할 테이블 (정규화되지 않음)에 일부 중복이 보인다
-
==============================
2.어쩌면 당신은 시작 지점으로 사용할 수 있습니다 :
어쩌면 당신은 시작 지점으로 사용할 수 있습니다 :
-- Recursive CTE to generate a list of dates for the month -- You'll probably want to play with making this dynamic WITH Dates AS ( SELECT CAST('2014-03-01' AS datetime) visitDate UNION ALL SELECT visitDate + 1 FROM Dates WHERE visitDate + 1 < '2014-04-01' ) -- Build a list of siteNames with each possible date in the month , SiteDates AS ( SELECT s.siteName, d.visitDate FROM SiteVisitEntry s CROSS APPLY Dates d GROUP BY s.siteName, d.visitDate ) -- Use a left anti-semi join to find the missing dates SELECT d.siteName, d.visitDate AS missingDate FROM SiteDates d LEFT JOIN SiteVisitEntry e /* Plug your actual table name here */ ON d.visitDate = e.visitDate AND d.siteName = e.siteName WHERE e.visitDate IS NULL OPTION (MAXRECURSION 0)
-
==============================
3.당신이 '달력 테이블'을 가지고있을 때 훨씬 간단해진다. 즉, 당신에게 가능한 관심의 모든 날짜를 유지하는 테이블입니다.
당신이 '달력 테이블'을 가지고있을 때 훨씬 간단해진다. 즉, 당신에게 가능한 관심의 모든 날짜를 유지하는 테이블입니다.
그 이유는 SQL이없는 무엇에보고 할 수 있다는 것입니다. 그런 다음, (예를 들면 다른 대답을 여기에서와 같이) 간격에 속해야 날짜를 만들 만든 날짜에보고하도록 SQL을 작성할 수 있습니다. 또는 당신은이 '달력 테이블을'지속에 그냥이 그냥 훨씬 더 빨리, 더 자주 다음 SQL 간단하지 만들고, 그것을 사용할 수 있습니다.
유사한 헛된에서, 당신이 방문을 가질 수있는 모든 사이트를 포함하는 차원 테이블이 있다고 가정? 그렇다면, 당신은 이런 식으로 뭔가를 얻을 수 ...
SELECT * FROM site CROSS JOIN calendar LEFT JOIN visit ON visit.site_id = site.id AND visit.visitDate = calendar.date WHERE calendar.date >= DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AND calendar.date < GETDATE() AND visit.visitDate IS NULL
-
==============================
4.여기에는 사용자 정의 함수 genrate을 구현하고있다.
여기에는 사용자 정의 함수 genrate을 구현하고있다.
CREATE FUNCTION genrate(@FROM_date date,@to_date date) RETURNS @tab table(missing date) AS BEGIN ;WITH cte AS ( SELECT @FROM_date missing UNION ALL SELECT DATEADD(DAY,1,missing) FROM cte WHERE missing <@to_date ) INSERT INTO @tab SELECT * FROM cte WHERE missing NOT IN (@FROM_date, @to_date) RETURN END
날짜 세트와 함께 실종 생성하는 데이터와 기능은 우리가 십자가를 할 건데 설정 적용을 사용.
SELECT user_No, product_name, amount, b.missing AS Missing_date FROM date_tab t CROSS APPLY DBO.genrate(T.ORDER_DATE,T.DELIVERY) b
from https://stackoverflow.com/questions/22329722/sql-server-displaying-missing-dates by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL Server 2008의 절 '에서'테이블 이름에 대한 변수를 사용하여 (0) | 2020.06.18 |
---|---|
[SQL] 에서 java.lang.UnsatisfiedLinkError : java.library.path에는 sqljdbc_auth 없다 (0) | 2020.06.18 |
[SQL] 열을 지정하지 않고 SQL INSERT. 무슨 일이야? (0) | 2020.06.18 |
[SQL] 시퀀스에서 다음 번호를 얻는 방법 (0) | 2020.06.18 |
[SQL] 주말을 제외한 SQL에서 두 날짜 사이의 계산 차이, (0) | 2020.06.18 |