지난 12 시간의 각 시간마다 하나의 레코드를 생성하는 쉬운 방법을 알고 있습니까?


12

지난 12 시간 동안의 이벤트 수를 시간별로 그룹화 한 보고서가 있습니다. 충분히 쉽게 들리지만, 어려움을 겪고있는 것은 차이를 다루는 레코드를 포함시키는 방법입니다.

다음은 예제 테이블입니다.

Event
(
  EventTime datetime,
  EventType int
)

데이터는 다음과 같습니다 :

  '2012-03-08 08:00:04', 1
  '2012-03-08 09:10:00', 2
  '2012-03-08 09:11:04', 2
  '2012-03-08 09:10:09', 1
  '2012-03-08 10:00:17', 4
  '2012-03-08 11:00:04', 1

해당 시간 동안 이벤트가 있는지 여부에 관계없이 지난 12 시간 동안 1 시간마다 하나의 레코드가있는 결과 세트를 작성해야합니다.

현재 시간이 '2012-03-08 11:00:00'이라고 가정하면 보고서에 (대략) 표시됩니다.

Hour  EventCount
----  ----------
23    0
0     0
1     0
2     0
3     0
4     0
5     0
6     0
7     0
8     1
9     3
10    1

나는 매일 한 시간마다 하나의 레코드가있는 테이블을 사용하는 솔루션을 생각해 냈습니다. 나는 where 절에서 UNION과 복잡한 논리를 사용하여 찾고있는 결과를 얻을 수 있었지만 누군가 더 우아한 해결책을 원했습니다.

답변:


21

SQL Server 2005+의 경우 재귀 적 CTE 루프 또는 루프를 사용하여 12 개의 레코드를 매우 쉽게 생성 할 수 있습니다. 다음은 재귀 CTE의 예입니다.

DECLARE @Date DATETIME
SELECT @Date = '20120308 11:00:00'

;WITH Dates AS
(
    SELECT DATEPART(HOUR,DATEADD(HOUR,-1,@Date)) [Hour], 
      DATEADD(HOUR,-1,@Date) [Date], 1 Num
    UNION ALL
    SELECT DATEPART(HOUR,DATEADD(HOUR,-1,[Date])), 
      DATEADD(HOUR,-1,[Date]), Num+1
    FROM Dates
    WHERE Num <= 11
)
SELECT [Hour], [Date]
FROM Dates

그런 다음 이벤트 테이블과 조인해야합니다.


2
당신이 게시 한 직후에 이것을 찾았습니다. explainextended.com/2009/10/21/... 은이 목적을 위해 CTE를 사용하여 저장된 테이블을보다 효율적임을 나타냅니다. 이것이 사실입니까? 닉 말했듯이, 아마 ...이 경우에 문제는 없지만
레이 Riffel에게

4
12 개 레코드가 필요한 경우 더 많은 행 수를 사용하여 차이를 만들 것이라고 생각합니다. 그러면 성능 저하가 전혀 없습니다.
Lamak

라막과 @swasheck. Heh. 나는 그것을 얻는 데 조금 늦었습니다 (이 스레드를 잃어 버렸습니다). 위의 주장을 뒷받침하기 위해 마지막으로 게시 한 답변을 참조하십시오. 그리고 모든 코드에는 누적 효과가 있습니다. 작성한 모든 코드 사람들이 16 배 더 "단지"빠르면 이와 같은 포럼 게시물의 절반이 더 이상 필요하지 않습니다. 더 빠른 코드를 작성하는 데 더 이상 (때로는 더 짧은 시간) 걸리지 않습니다.
Jeff Moden

10

탈리 테이블은 이와 같은 것들에 사용될 수 있습니다. 그들은 매우 효율적일 수 있습니다. 아래에 탈리 테이블을 만듭니다. 예제를 위해 24 행으로 만 집계 테이블을 만들었지 만 다른 용도로 사용하려는 많은 테이블을 만들 수 있습니다.

SELECT TOP 24 
        IDENTITY(INT,1,1) AS N
   INTO dbo.Tally
   FROM Master.dbo.SysColumns sc1,
        Master.dbo.SysColumns sc2

--===== Add a Primary Key to maximize performance
  ALTER TABLE dbo.Tally
    ADD CONSTRAINT PK_Tally_N 
        PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100

귀하의 테이블이 dbo.tblEvents라고 가정하고 아래 쿼리를 실행하십시오. 나는 이것이 당신이 찾고있는 것이라고 믿습니다.

SELECT t.n, count(e.EventTime)
FROM dbo.Tally t
LEFT JOIN dbo.tblEvent e  on t.n = datepart(hh, e.EventTime)
GROUP BY t.n
ORDER BY t.n

신용이 다음 링크로 이동한다고 생각합니다.

http://www.sqlservercentral.com/articles/T-SQL/62867/

http://www.sqlservercentral.com/articles/T-SQL/74118/


+1이지만 의미 적으로는 테이블이 아니라 숫자 테이블입니다.
Aaron Bertrand

1
"Tally"의 정의 중 하나는 "To Count"입니다. "탈리 테이블"은 계산에 사용되는 길고 마른 스틱 인 "탈리 스틱"의 이름을 따서 명명되었습니다.
Jeff Moden

7

첫째, 마지막 의견 이후 답변이 지연된 것에 대해 사과드립니다.

주제는 재귀 CTE (여기부터 rCTE)를 사용하면 행 수가 적기 때문에 충분히 빠르게 실행된다는 의견에서 나타났습니다. 그것은 그렇게 보일지 모르지만, 진실에서 더 나아질 수는 없습니다.

전체 테이블 및 전체 기능 구축

테스트를 시작하기 전에 적절한 클러스터형 인덱스와 Itzik Ben-Gan 스타일 탈리 함수를 사용하여 실제 탈리 테이블을 만들어야합니다. 또한 TempDB에서이 모든 작업을 수행하여 실수로 다른 사람의 이익을 떨어 뜨리지 않도록합니다.

다음은 Tally Table을 빌드하는 코드와 Itzik의 멋진 코드의 현재 프로덕션 버전입니다.

--===== Do this in a nice, safe place that everyone has
    USE tempdb
;
--===== Create/Recreate a Physical Tally Table
     IF OBJECT_ID('dbo.Tally','U') IS NOT NULL
        DROP TABLE dbo.Tally
;
     -- Note that the ISNULL makes a NOT NULL column
 SELECT TOP 1000001
        N = ISNULL(ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1,0)
   INTO dbo.Tally
   FROM      sys.all_columns ac1
  CROSS JOIN sys.all_columns ac2
;
  ALTER TABLE dbo.Tally
    ADD CONSTRAINT PK_Tally PRIMARY KEY CLUSTERED (N)
;
--===== Create/Recreate a Tally Function
     IF OBJECT_ID('dbo.fnTally','IF') IS NOT NULL
        DROP FUNCTION dbo.fnTally
;
GO
 CREATE FUNCTION [dbo].[fnTally]
/**********************************************************************************************************************
 Purpose:
 Return a column of BIGINTs from @ZeroOrOne up to and including @MaxN with a max value of 1 Trillion.

 As a performance note, it takes about 00:02:10 (hh:mm:ss) to generate 1 Billion numbers to a throw-away variable.

 Usage:
--===== Syntax example (Returns BIGINT)
 SELECT t.N
   FROM dbo.fnTally(@ZeroOrOne,@MaxN) t
;

 Notes:
 1. Based on Itzik Ben-Gan's cascading CTE (cCTE) method for creating a "readless" Tally Table source of BIGINTs.
    Refer to the following URLs for how it works and introduction for how it replaces certain loops. 
    http://www.sqlservercentral.com/articles/T-SQL/62867/
    http://sqlmag.com/sql-server/virtual-auxiliary-table-numbers
 2. To start a sequence at 0, @ZeroOrOne must be 0 or NULL. Any other value that's convertable to the BIT data-type
    will cause the sequence to start at 1.
 3. If @ZeroOrOne = 1 and @MaxN = 0, no rows will be returned.
 5. If @MaxN is negative or NULL, a "TOP" error will be returned.
 6. @MaxN must be a positive number from >= the value of @ZeroOrOne up to and including 1 Billion. If a larger
    number is used, the function will silently truncate after 1 Billion. If you actually need a sequence with
    that many values, you should consider using a different tool. ;-)
 7. There will be a substantial reduction in performance if "N" is sorted in descending order.  If a descending 
    sort is required, use code similar to the following. Performance will decrease by about 27% but it's still
    very fast especially compared with just doing a simple descending sort on "N", which is about 20 times slower.
    If @ZeroOrOne is a 0, in this case, remove the "+1" from the code.

    DECLARE @MaxN BIGINT; 
     SELECT @MaxN = 1000;
     SELECT DescendingN = @MaxN-N+1 
       FROM dbo.fnTally(1,@MaxN);

 8. There is no performance penalty for sorting "N" in ascending order because the output is explicity sorted by
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

 Revision History:
 Rev 00 - Unknown     - Jeff Moden 
        - Initial creation with error handling for @MaxN.
 Rev 01 - 09 Feb 2013 - Jeff Moden 
        - Modified to start at 0 or 1.
 Rev 02 - 16 May 2013 - Jeff Moden 
        - Removed error handling for @MaxN because of exceptional cases.
 Rev 03 - 22 Apr 2015 - Jeff Moden
        - Modify to handle 1 Trillion rows for experimental purposes.
**********************************************************************************************************************/
        (@ZeroOrOne BIT, @MaxN BIGINT)
RETURNS TABLE WITH SCHEMABINDING AS 
 RETURN WITH
  E1(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
            SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
            SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
            SELECT 1)                                  --10E1 or 10 rows
, E4(N) AS (SELECT 1 FROM E1 a, E1 b, E1 c, E1 d)      --10E4 or 10 Thousand rows
,E12(N) AS (SELECT 1 FROM E4 a, E4 b, E4 c)            --10E12 or 1 Trillion rows                 
            SELECT N = 0 WHERE ISNULL(@ZeroOrOne,0)= 0 --Conditionally start at 0.
             UNION ALL 
            SELECT TOP(@MaxN) N = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E12 -- Values from 1 to @MaxN
;
GO

그건 그렇고 ... 백만 및 하나의 행 Tally Table을 작성하고 약 1 초 정도 클러스터 색인을 추가했습니다. rCTE로 THAT을 시도하고 시간이 얼마나 걸리는지 확인하십시오! ;-)

일부 테스트 데이터 구축

테스트 데이터도 필요합니다. 예, rCTE를 포함하여 테스트 할 모든 기능이 12 행 동안 밀리 초 이하로 실행되지만 많은 사람들이 빠지는 함정입니다. 나중에이 트랩에 대해 더 이야기 하겠지만 지금은 각 함수를 4 만 번 호출하는 것을 시뮬레이션 할 수 있습니다. 이는 8 시간 동안 상점의 특정 함수가 몇 번 호출되는지에 관한 것입니다. 대규모 온라인 소매업에서 이러한 기능을 몇 번이나 호출 할 수 있는지 상상해보십시오.

여기 임의의 날짜로 40,000 개의 행을 작성하는 코드가 있습니다. 각 행에는 추적 목적으로 만 행 번호가 있습니다. 여기서 시간이 중요하지 않기 때문에 시간을 내내 만드는 데 시간이 걸리지 않았습니다.

--===== Do this in a nice, safe place that everyone has
    USE tempdb
;
--===== Create/Recreate a Test Date table
     IF OBJECT_ID('dbo.TestDate','U') IS NOT NULL
        DROP TABLE dbo.TestDate
;
DECLARE  @StartDate DATETIME
        ,@EndDate   DATETIME
        ,@Rows      INT
;
 SELECT  @StartDate = '2010' --Inclusive
        ,@EndDate   = '2020' --Exclusive
        ,@Rows      = 40000  --Enough to simulate an 8 hour day where I work
;
 SELECT  RowNum       = IDENTITY(INT,1,1)
        ,SomeDateTime = RAND(CHECKSUM(NEWID()))*DATEDIFF(dd,@StartDate,@EndDate)+@StartDate
   INTO dbo.TestDate
   FROM dbo.fnTally(1,@Rows)
;

12 시간 동안 행하는 몇 가지 기능 구축

다음으로 rCTE 코드를 함수로 변환하고 3 개의 다른 함수를 작성했습니다. 그것들은 모두 고성능 iTVF (인라인 테이블 값 함수)로 만들어졌습니다. iTVF에는 Scalar 또는 mTVF (Multi-statement Table Valued Functions)와 같은 BEGIN이 없으므로 항상 알 수 있습니다.

이 4 가지 함수를 빌드하는 코드는 다음과 같습니다. 나는 그것들을 쉽게 식별하기 위해 사용하는 방법이 아니라 사용하는 메소드의 이름을 따서 명명했습니다.

--=====  CREATE THE iTVFs
--===== Do this in a nice, safe place that everyone has
    USE tempdb
;
-----------------------------------------------------------------------------------------
     IF OBJECT_ID('dbo.OriginalrCTE','IF') IS NOT NULL
        DROP FUNCTION dbo.OriginalrCTE
;
GO
 CREATE FUNCTION dbo.OriginalrCTE
        (@Date DATETIME)
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
WITH Dates AS
(
    SELECT DATEPART(HOUR,DATEADD(HOUR,-1,@Date)) [Hour], 
      DATEADD(HOUR,-1,@Date) [Date], 1 Num
    UNION ALL
    SELECT DATEPART(HOUR,DATEADD(HOUR,-1,[Date])), 
      DATEADD(HOUR,-1,[Date]), Num+1
    FROM Dates
    WHERE Num <= 11
)
SELECT [Hour], [Date]
FROM Dates
GO
-----------------------------------------------------------------------------------------
     IF OBJECT_ID('dbo.MicroTally','IF') IS NOT NULL
        DROP FUNCTION dbo.MicroTally
;
GO
 CREATE FUNCTION dbo.MicroTally
        (@Date DATETIME)
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
 SELECT  [Hour] = DATEPART(HOUR,DATEADD(HOUR,t.N,@Date))
        ,[DATE] = DATEADD(HOUR,t.N,@Date)
   FROM (VALUES (-1),(-2),(-3),(-4),(-5),(-6),(-7),(-8),(-9),(-10),(-11),(-12))t(N)
;
GO
-----------------------------------------------------------------------------------------
     IF OBJECT_ID('dbo.PhysicalTally','IF') IS NOT NULL
        DROP FUNCTION dbo.PhysicalTally
;
GO
 CREATE FUNCTION dbo.PhysicalTally
        (@Date DATETIME)
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
 SELECT  [Hour] = DATEPART(HOUR,DATEADD(HOUR,-t.N,@Date))
        ,[DATE] = DATEADD(HOUR,-t.N,@Date)
   FROM dbo.Tally t
  WHERE N BETWEEN 1 AND 12
;
GO
-----------------------------------------------------------------------------------------
     IF OBJECT_ID('dbo.TallyFunction','IF') IS NOT NULL
        DROP FUNCTION dbo.TallyFunction
;
GO
 CREATE FUNCTION dbo.TallyFunction
        (@Date DATETIME)
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
 SELECT  [Hour] = DATEPART(HOUR,DATEADD(HOUR,-t.N,@Date))
        ,[DATE] = DATEADD(HOUR,-t.N,@Date)
   FROM dbo.fnTally(1,12) t
;
GO

테스트 하니스를 구축하여 기능 테스트

마지막으로 테스트 하네스가 필요합니다. 기본 점검을 수행 한 다음 각 기능을 동일한 방식으로 테스트합니다.

테스트 하네스 코드는 다음과 같습니다.

PRINT '--========== Baseline Select =================================';
DECLARE @Hour INT, @Date DATETIME
;
    SET STATISTICS TIME,IO ON;
 SELECT  @Hour = RowNum
        ,@Date = SomeDateTime
   FROM dbo.TestDate
  CROSS APPLY dbo.fnTally(1,12);
    SET STATISTICS TIME,IO OFF;
GO
PRINT '--========== Orginal Recursive CTE ===========================';
DECLARE @Hour INT, @Date DATETIME
;

    SET STATISTICS TIME,IO ON;
 SELECT  @Hour = fn.[Hour]
        ,@Date = fn.[Date]
   FROM dbo.TestDate td
  CROSS APPLY dbo.OriginalrCTE(td.SomeDateTime) fn;
    SET STATISTICS TIME,IO OFF;
GO
PRINT '--========== Dedicated Micro-Tally Table =====================';
DECLARE @Hour INT, @Date DATETIME
;

    SET STATISTICS TIME,IO ON;
 SELECT  @Hour = fn.[Hour]
        ,@Date = fn.[Date]
   FROM dbo.TestDate td
  CROSS APPLY dbo.MicroTally(td.SomeDateTime) fn;
    SET STATISTICS TIME,IO OFF;
GO
PRINT'--========== Physical Tally Table =============================';
DECLARE @Hour INT, @Date DATETIME
;
    SET STATISTICS TIME,IO ON;
 SELECT  @Hour = fn.[Hour]
        ,@Date = fn.[Date]
   FROM dbo.TestDate td
  CROSS APPLY dbo.PhysicalTally(td.SomeDateTime) fn;
    SET STATISTICS TIME,IO OFF;
GO
PRINT'--========== Tally Function ===================================';
DECLARE @Hour INT, @Date DATETIME
;
    SET STATISTICS TIME,IO ON;
 SELECT  @Hour = fn.[Hour]
        ,@Date = fn.[Date]
   FROM dbo.TestDate td
  CROSS APPLY dbo.TallyFunction(td.SomeDateTime) fn;
    SET STATISTICS TIME,IO OFF;
GO

위의 테스트 하니스에서 주목해야 할 것은 모든 출력을 "throwaway"변수로 분류한다는 것입니다. 이는 디스크 또는 화면 왜곡 결과를 출력하지 않고 성능 측정을 가능한 한 순수하게 유지하는 것입니다.

설정된 통계에 대한주의 사항

또한 테스터들에게주의 할 점은 ... Scalar 또는 mTVF 함수를 테스트 할 때 SET STATISTICS를 사용해서는 안됩니다. 이 테스트와 같은 iTVF 기능에서만 안전하게 사용할 수 있습니다. SET STATISTICS는 SCALAR 기능이 실제로없는 것보다 수백 배 느리게 실행되는 것으로 입증되었습니다. 그래, 나는 또 다른 풍차를 기울이려고 노력하고 있지만 그것은 전체 '너덜 한 기사 길이의 게시물이 될 것이고 나는 그럴 시간이 없다. SQLServerCentral.com에 대한 기사가 있지만 그 링크를 게시하는 것은 의미가 없습니다.

테스트 결과

6GB RAM이있는 작은 i5 랩톱에서 테스트 장치를 실행할 때의 테스트 결과는 다음과 같습니다.

--========== Baseline Select =================================
Table 'Worktable'. Scan count 1, logical reads 82309, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestDate'. Scan count 1, logical reads 105, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 203 ms,  elapsed time = 206 ms.
--========== Orginal Recursive CTE ===========================
Table 'Worktable'. Scan count 40001, logical reads 2960000, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestDate'. Scan count 1, logical reads 105, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 4258 ms,  elapsed time = 4415 ms.
--========== Dedicated Micro-Tally Table =====================
Table 'Worktable'. Scan count 1, logical reads 81989, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestDate'. Scan count 1, logical reads 105, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 234 ms,  elapsed time = 235 ms.
--========== Physical Tally Table =============================
Table 'Worktable'. Scan count 1, logical reads 81989, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestDate'. Scan count 1, logical reads 105, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Tally'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 250 ms,  elapsed time = 252 ms.
--========== Tally Function ===================================
Table 'Worktable'. Scan count 1, logical reads 81989, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TestDate'. Scan count 1, logical reads 105, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 250 ms,  elapsed time = 253 ms.

데이터를 선택하는 "BASELINE SELECT"(동일한 양의 리턴을 시뮬레이트하기 위해 각 행이 12 번 생성됨)는 약 1/5 초에 올랐습니다. 다른 모든 것은 약 1/4 초에 들어 왔습니다. 피의 rCTE 기능을 제외한 모든 것. 4 초 및 1/4 초 또는 16 배 더 오래 걸렸습니다 (1,600 % 느림).

논리적 읽기 (메모리 IO)를 살펴보십시오. rCTE는 무려 2,960,000 (거의 3 백만 건)을 소비했지만 다른 기능은 약 82,100 만 소비했습니다. 이는 rCTE가 다른 기능보다 34.3 배 더 많은 메모리 IO를 소비했음을 의미합니다.

생각을 닫기

요약하자. 이 "작은"12 행 작업을 수행하는 rCTE 방법은 다른 기능보다 16 TIMES (1,600 %) 더 많은 CPU (및 지속 시간)와 34.3 TIMES (3,430 %) 더 많은 메모리 IO를 사용했습니다.

허 .. 무슨 생각하는지 알아 "큰 거래! 하나의 기능 일뿐입니다."

예, 동의했지만 다른 기능은 몇 개입니까? 기능 이외의 다른 장소는 몇 개입니까? 그리고 한 번에 12 행 이상으로 작동하는 것들이 있습니까? 그리고 분석법을 찾고있는 누군가가 그 rCTE 코드를 훨씬 더 크게 복사 할 가능성이 있습니까?

좋아, 무딘 시간. 행 수나 사용량이 제한되어 있기 때문에 성능 문제가있는 코드를 정당화하는 것은 전혀 의미가 없습니다. MPP 상자를 수백만 달러에 구입할 때를 제외하고 (그런 기계에서 작동하도록 코드를 다시 작성하는 비용은 말할 것도 없습니다) 코드를 16 배 빠르게 실행하는 기계를 구입할 수는 없습니다 (SSD의 원화) 우리가 그것을 테스트 할 때이 모든 것들이 고속 메모리에있었습니다.) 성능은 코드에 있습니다. 좋은 성능은 좋은 코드입니다.

모든 코드가 16 배 더 빨리 실행되는지 상상할 수 있습니까?

행 수가 적거나 사용량이 적을 때 성능이 나쁘거나 성능이 떨어지는 코드를 정당화하지 마십시오. 그렇다면 CPU와 디스크를 충분히 시원하게 유지하기 위해 기울어 졌다고 비난받은 ​​풍차 중 하나를 빌려야 할 수도 있습니다. ;-)

"전체적으로"라는 단어

네 ... 동의합니다. 의미 적으로 말해서 Tally Table은 "tallies"가 아닌 숫자를 포함합니다. 주제에 대한 나의 원래 기사 (기술에 관한 최초의 기사는 아니었지만 그것은 나의 첫 기사였다)에서 나는 그것이 포함 된 것이 아니라 그것이하는 것 때문에 "탈리 (Tally)"라고 불렀다. 루핑 대신 "계산"하고 무언가를 "계산"하는 데 사용됩니다. ;-) 당신이 무엇을할지 ... Numbers Table, Tally Table, Sequence Table, 뭐든간에. 상관 없어요 나를 위해, "Tally"는 더 많은 의미를 지니고 있으며 좋은 게으른 DBA이기 때문에 7 대신 5 글자 (2는 동일) 만 포함하며 대부분의 사람들에게 말하기가 더 쉽습니다. 또한 테이블에 대한 명명 규칙을 따르는 "단일"입니다. ;-) 그것은 또한 60 년대의 책에서 페이지를 포함하는 기사가 그것을 호출했습니다. 나는 항상 그것을 "탈리 테이블"이라고 부르며 여전히 당신이나 다른 사람이 무엇을 의미하는지 알게 될 것입니다. 나는 또한 전염병과 같은 헝가리 표기법을 피하지만 "fnTally"라는 함수를 호출하여 "음, 당신이 내가 보여준 eff-en Tally Function을 사용하면 실제로 성능 문제가 없을 것"이라고 말할 수 있습니다. HR 위반. ;-) 실제로 HR 위반이 아닙니다. ;-) 실제로 HR 위반이 아닙니다. ;-)

내가 더 걱정하는 것은 성능 문제가있는 rCTE 및 기타 형태의 숨겨진 RBAR과 같은 것에 의존하는 대신 올바르게 사용하는 법을 배우는 사람들입니다.


2

필요한 RIGHT JOIN시간마다 하나의 레코드를 반환하는 쿼리 를 사용 하여 데이터가 필요합니다.

현재 시간에서 시간으로 뺄 수있는 행 번호를 얻는 몇 가지 방법 은 이것을 참조하십시오 .

Oracle에서 dual에 대한 계층 적 쿼리는 행을 생성합니다.

SELECT to_char(sysdate-level/24,'HH24') FROM dual CONNECT BY Level <=24;

내가 문제가있는 것은 "시간마다 하나의 레코드를 반환하는 쿼리"입니다. 지난 12 시간 (또는 24 시간)의 모든 시간마다 12 (또는 24) 개의 레코드를 생성하는 방법을 찾으려고 노력했습니다.
datagod
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.