복붙노트

[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. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    4.당신이 그것을에서 24까지의 숫자 1을 가진 다른 테이블을 사용하여 "왼쪽 외부 조인"사용할 수있는 것 같은데 ...

    당신이 그것을에서 24까지의 숫자 1을 가진 다른 테이블을 사용하여 "왼쪽 외부 조인"사용할 수있는 것 같은데 ...

  5. ==============================

    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을 수행하는 데 사용할 수 있습니다. 아니 단정하고 깔끔하지만, 작동 대부분의 장소로.

  6. 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