[SQL] 쿼리의 반환에 날짜 삽입 곳에 아무도 없다
SQL쿼리의 반환에 날짜 삽입 곳에 아무도 없다
우리는 하루에 시간당 이벤트의 수를 계산하는 쿼리를 구축하고있다. 대부분의 날은 쿼리가 표시 시간 당 활동의 수를 실행하지만 빈틈과 쿼리 제외이가있는 곳 그러므로 모든 활동을하지 않는 시간이있다. 우리는 여전히 활동이 제로 값을 다음 차트 할 수있는 제로 있도록 표시되지 않습니다 시간을 보여주고 싶어요. 쿼리 우리는이 같은 모양을 사용하여 ...
select datepart(Year, dev_time) as Year,
datepart(Month, dev_time) as Month,
datepart(Day, dev_time) as Day,
datepart(Hour, dev_time) as Hour,
count(tdm_msg) as Total_ACTIVITES
from TCKT_ACT
where tdm_msg = ‘4162′ and dev_time >= DATEADD(day, - 1, GETDATE())
group by datepart(Year, dev_time) ,
datepart(Month, dev_time) ,
datepart(Day, dev_time),
datepart(Hour, dev_time)
order by datepart(Year, dev_time) asc,
datepart(Month, dev_time) asc,
datepart(Day, dev_time) asc,
datepart(Hour, dev_time) asc
해결법
-
==============================
1.어떻게 든 일 및 시간의 테이블을 필요로가는거야, 그리고 당신은 외부가 테이블과 쿼리 사이에 가입해야 할 것입니다. 여기에 내가 그것을 할 것입니다 방법입니다. 참고이 솔루션은 당신이 그 플랫폼 SQL Server 2005 및 2008 만 작업이없는 경우, 당신은 실제로 당신의 해제에 가입 할 수있는 데이터베이스의 배의 테이블을 만들어야합니다 :
어떻게 든 일 및 시간의 테이블을 필요로가는거야, 그리고 당신은 외부가 테이블과 쿼리 사이에 가입해야 할 것입니다. 여기에 내가 그것을 할 것입니다 방법입니다. 참고이 솔루션은 당신이 그 플랫폼 SQL Server 2005 및 2008 만 작업이없는 경우, 당신은 실제로 당신의 해제에 가입 할 수있는 데이터베이스의 배의 테이블을 만들어야합니다 :
DECLARE @MinDate DATETIME; SET @MinDate = CONVERT(varchar, GETDATE(), 101); WITH times AS ( SELECT @MinDate as dt, 1 as depth UNION ALL SELECT DATEADD(hh, depth, @MinDate), 1 + depth as depth FROM times WHERE DATEADD(hh, depth, @MinDate) <= GETDATE()) SELECT DATEPART(YEAR, t.dt) as [Year], DATEPART(MONTH, t.dt) as [Month], DATEPART(DAY, t.dt) as [Day], DATEPART(HOUR, t.dt) as [Hour], COUNT(tdm_msg) as Total_ACTIVITES FROM times t LEFT JOIN (SELECT * FROM TCKT_ACT WHERE tdm_msg = '4162' and dev_time >= @MinDate) a ON DATEPART(HOUR, t.dt) = DATEPART(HOUR, a.dev_time) AND MONTH(t.dt) = MONTH(a.dev_time) AND DAY(t.dt) = DAY(a.dev_time) AND YEAR(t.dt) = YEAR(a.dev_time) GROUP BY DATEPART(YEAR, t.dt) , DATEPART(MONTH, t.dt) , DATEPART(DAY, t.dt), DATEPART(HOUR, t.dt) ORDER BY DATEPART(YEAR, t.dt) asc, DATEPART(MONTH, t.dt) asc, DATEPART(DAY, t.dt) asc, DATEPART(HOUR, t.dt) asc OPTION (MAXRECURSION 0); /* Just in case you want a longer timespan later on... */
상단에있는 문으로 재귀 공통 테이블 표현식이라고하고, 여기에이 같은 요소의 상대적으로 작은 숫자를 순차적으로 테이블을 생성하는 좋은 방법입니다 있습니다.
-
==============================
2.우선은 설명 재귀 공통 테이블 쿼리를 기반으로 테이블 함수를 생성 데이브 마클 (이 데이브 나를 보여 주셔서 감사합니다!). 내가 한 번만 기능을해야하고 내가 어떤 간격을 분석 사용할 수 있기 때문에 매우 달콤한입니다.
우선은 설명 재귀 공통 테이블 쿼리를 기반으로 테이블 함수를 생성 데이브 마클 (이 데이브 나를 보여 주셔서 감사합니다!). 내가 한 번만 기능을해야하고 내가 어떤 간격을 분석 사용할 수 있기 때문에 매우 달콤한입니다.
if exists (select * from dbo.sysobjects where name = 'fn_daterange') drop function fn_daterange; go create function fn_daterange ( @MinDate as datetime, @MaxDate as datetime, @intval as datetime ) returns table --************************************************************************** -- Procedure: fn_daterange() -- Author: Ron Savage -- Date: 12/16/2008 -- -- Description: -- This function takes a starting and ending date and an interval, then -- returns a table of all the dates in that range at the specified interval. -- -- Change History: -- Date Init. Description -- 12/16/2008 RS Created. -- ************************************************************************** as return WITH times (startdate, enddate, intervl) AS ( SELECT @MinDate as startdate, @MinDate + @intval - .0000001 as enddate, @intval as intervl UNION ALL SELECT startdate + intervl as startdate, enddate + intervl as enddate, intervl as intervl FROM times WHERE startdate + intervl <= @MaxDate ) select startdate, enddate from times; go
당신은 그 자체가 그 함수에서 선택합니까 그렇다면이 같은 시간 간격의 테이블을 얻을 :
fn_daterange (/ 2008 10시 0분 0초 '12 / 14 '/ 14 / 2008 20시 0분 0초 '12', '01 : 00 : 00 ')
보고:
startdate enddate intervl ----------------------- ----------------------- ----------------------- 2008-12-14 10:00:00.000 2008-12-14 10:59:59.997 1900-01-01 01:00:00.000 2008-12-14 11:00:00.000 2008-12-14 11:59:59.997 1900-01-01 01:00:00.000 2008-12-14 12:00:00.000 2008-12-14 12:59:59.997 1900-01-01 01:00:00.000 2008-12-14 13:00:00.000 2008-12-14 13:59:59.997 1900-01-01 01:00:00.000 2008-12-14 14:00:00.000 2008-12-14 14:59:59.997 1900-01-01 01:00:00.000 2008-12-14 15:00:00.000 2008-12-14 15:59:59.997 1900-01-01 01:00:00.000 2008-12-14 16:00:00.000 2008-12-14 16:59:59.997 1900-01-01 01:00:00.000 2008-12-14 17:00:00.000 2008-12-14 17:59:59.997 1900-01-01 01:00:00.000 2008-12-14 18:00:00.000 2008-12-14 18:59:59.997 1900-01-01 01:00:00.000 2008-12-14 19:00:00.000 2008-12-14 19:59:59.997 1900-01-01 01:00:00.000 2008-12-14 20:00:00.000 2008-12-14 20:59:59.997 1900-01-01 01:00:00.000
그럼 이벤트 데이터의 샘플 테이블을 만든 :
eventdate eventnote ----------------------- -------------------- 2008-12-14 10:01:00.000 oo! an event! 2008-12-14 10:01:00.000 oo! an event! 2008-12-14 10:01:00.000 oo! an event! 2008-12-14 10:01:00.000 oo! an event! 2008-12-14 10:23:00.000 oo! an event! 2008-12-14 10:23:00.000 oo! an event! 2008-12-14 10:23:00.000 oo! an event! 2008-12-14 11:23:00.000 oo! an event! 2008-12-14 11:23:00.000 oo! an event! 2008-12-14 11:23:00.000 oo! an event! 2008-12-14 11:23:00.000 oo! an event! 2008-12-14 11:23:00.000 oo! an event! 2008-12-14 14:23:00.000 oo! an event! 2008-12-14 14:23:00.000 oo! an event! 2008-12-14 14:23:00.000 oo! an event! 2008-12-14 19:23:00.000 oo! an event! 2008-12-14 19:23:00.000 oo! an event! 2008-12-14 19:23:00.000 oo! an event! 2008-12-14 19:23:00.000 oo! an event! 2008-12-14 19:00:00.000 oo! an event! 2008-12-14 19:00:00.000 oo! an event! 2008-12-14 19:00:00.000 oo! an event! 22 Row(s) affected
그럼 난과 같이 왼쪽 외부 조인과 함께 그들을 중독 :
select dr.startdate, dr.enddate, count(me.eventdate) as eventcount from fn_daterange('12/14/2008 10:00:00', '12/14/2008 20:00:00', '01:00:00' ) dr LEFT OUTER JOIN myevents me on ( me.eventdate between dr.startdate and dr.enddate) group by dr.startdate, dr.enddate startdate enddate eventcount ----------------------- ----------------------- ---------- 2008-12-14 10:00:00.000 2008-12-14 10:59:59.993 7 2008-12-14 11:00:00.000 2008-12-14 11:59:59.993 5 2008-12-14 12:00:00.000 2008-12-14 12:59:59.993 0 2008-12-14 13:00:00.000 2008-12-14 13:59:59.993 0 2008-12-14 14:00:00.000 2008-12-14 14:59:59.993 3 2008-12-14 15:00:00.000 2008-12-14 15:59:59.993 0 2008-12-14 16:00:00.000 2008-12-14 16:59:59.993 0 2008-12-14 17:00:00.000 2008-12-14 17:59:59.993 0 2008-12-14 18:00:00.000 2008-12-14 18:59:59.993 0 2008-12-14 19:00:00.000 2008-12-14 19:59:59.993 7 2008-12-14 20:00:00.000 2008-12-14 20:59:59.993 0 11 Row(s) affected
그 거룩한 뽑는는 달콤한 - 나는 직장에서 분석의 모든 종류를 위해 이것을 사용할 수 있습니다! :-)
공통 테이블 쿼리에 대한 정보를 주셔서 감사합니다 질문에 대한 프레드와 데이브!
론
-
==============================
3.우리는 약간의 성능이 DB2 / z 메인 프레임의 가게에서 소프트웨어를 모니터링하지만, 존재와 비슷한 문제가 있었다, 우리는 결과의 그 종류를 얻기 위해 SQL 체조를 할 필요에 대한 죽었어 세트. 그들은 검색 모든 행에 '기능'을 수행 SQL 쿼리는 악명 기어 오를 수 있고 우리가 그들을 사용하려고하면 DBA는 필드 날이 우리를 웃고있을 것입니다.
우리는 약간의 성능이 DB2 / z 메인 프레임의 가게에서 소프트웨어를 모니터링하지만, 존재와 비슷한 문제가 있었다, 우리는 결과의 그 종류를 얻기 위해 SQL 체조를 할 필요에 대한 죽었어 세트. 그들은 검색 모든 행에 '기능'을 수행 SQL 쿼리는 악명 기어 오를 수 있고 우리가 그들을 사용하려고하면 DBA는 필드 날이 우리를 웃고있을 것입니다.
대신, 우리는 쉽게 각 행 (분명히 우리의 DBA가, 더 많은 디스크 공간을 사용하여 단지 더 많은 CPU 꿀꿀 상관 없어) 이벤트의 수를 포함하는 데이터베이스 스키마를 리팩토링을 발견했다. 귀하의 경우에는, 그건 당신이 삽입하는 모든 행 (즉, 각 이벤트) 1로 설정합니다 열라고 tdm_quant을 추가하는 것입니다.
그런 다음 검색 결과의 다섯 번째 필드는 동일한 결과를 달성 할 수 합 (tdm_quant)을 카운트 (tdm_msg)로 변경한다.
tdm_quant 필드가 0으로 설정된다 당신이 (한 시간 후, 또는 이들의 24 하루의 시작에, 또는 당신이 원하는 경우 1 월 1 일 전체 년 가치를 채우) 특별한 레코드를 삽입 할 수뿐만 아니라. 제로이기 때문에,이 기록은 합 (tdm_quant)에 영향을주지 않습니다하지만 당신이 원하는 행동을 얻을 것이다, 행에는 이벤트가 그 시간에 발생하지 Total_ACTIVITIES 제로있을 것이다 하루의 모든 시간 동안 돌아왔다.
쿼리의 나머지는 변경할 필요가 없습니다.
-
==============================
4.당신이 그것을에서 24까지의 숫자 1을 가진 다른 테이블을 사용하여 "왼쪽 외부 조인"사용할 수있는 것 같은데 ...
당신이 그것을에서 24까지의 숫자 1을 가진 다른 테이블을 사용하여 "왼쪽 외부 조인"사용할 수있는 것 같은데 ...
-
==============================
5.기본적인 대답은 여기에 왼쪽 외부 조인 (LOJ)를 포함하고, 그 이후 명시 적 COUNT (열) 널 (null)을 계산하지 않고 COUNT (*)가 모든 행을 계산합니다. 어려운 부분은 LOJ을 수행하는 대한 테이블을 생성한다. 절 및 순환 용액으로는 DBMS의 숫자에서 작동합니다 (MS SQL 서버, 분명히, 그리고 거의 확실 DB2 - 아마 다른 사람을 너무).
기본적인 대답은 여기에 왼쪽 외부 조인 (LOJ)를 포함하고, 그 이후 명시 적 COUNT (열) 널 (null)을 계산하지 않고 COUNT (*)가 모든 행을 계산합니다. 어려운 부분은 LOJ을 수행하는 대한 테이블을 생성한다. 절 및 순환 용액으로는 DBMS의 숫자에서 작동합니다 (MS SQL 서버, 분명히, 그리고 거의 확실 DB2 - 아마 다른 사람을 너무).
대부분의 DBMS는 임시 테이블 및 저장 프로 시저를 지원; 조합은 날짜 / 시간 필드 값의 적절한 세트로 테이블을 채우고, 다음 (... 또는, 더 정확하게, temp_table LEFT OUTER로부터 main_table 가입) 해당 테이블에 대해 LOJ을 수행하는 데 사용할 수 있습니다. 아니 단정하고 깔끔하지만, 작동 대부분의 장소로.
from https://stackoverflow.com/questions/373490/insert-dates-in-the-return-from-a-query-where-there-is-none by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 노드를 반복 SQL Server 용의 XML 경로 메이크업 (0) | 2020.05.28 |
---|---|
[SQL] 어떻게 이름에 대괄호가 SQL 서버에 뭔가 이름을 바꾸려면? (0) | 2020.05.28 |
[SQL] SQL 서버 - 자연의 부족 / X Y가 사용 JOIN (필드) 가입 (0) | 2020.05.28 |
[SQL] 다른 데이터베이스에서 쿼리의 결과에 따라 데이터베이스 쿼리 (0) | 2020.05.28 |
[SQL] 콤마 구별 값 MySQL의 PHP 선택 횟수 데이터 (태그)를 구분 (0) | 2020.05.28 |