표준 mysql 함수를 사용하면 두 날짜 사이의 날짜 목록을 반환하는 쿼리를 작성하는 방법이 있습니다.
예를 들어 2009-01-01 및 2009-01-13이 주어지면 값이있는 하나의 열 테이블을 반환합니다.
2009-01-01
2009-01-02
2009-01-03
2009-01-04
2009-01-05
2009-01-06
2009-01-07
2009-01-08
2009-01-09
2009-01-10
2009-01-11
2009-01-12
2009-01-13
편집 : 내가 명확하지 않은 것 같습니다. 이 목록을 생성하고 싶습니다. 데이터베이스에 (날짜 시간 기준) 값이 저장되어 있지만 위와 같이 날짜 목록에 대한 왼쪽 외부 조인에서 집계되기를 원합니다 (일부 조인의 오른쪽에서 며칠 동안 null이 예상되며 이것을 처리합니다 ).
답변
이 저장 프로 시저를 사용하여 time_intervals 라는 임시 테이블에 필요한 간격을 생성 한 다음 임시 time_intervals 테이블로 데이터 테이블을 JOIN하고 집계합니다 .
프로시 저는 지정된 모든 유형의 간격을 생성 할 수 있습니다.
call make_intervals('2009-01-01 00:00:00','2009-01-10 00:00:00',1,'DAY')
.
select * from time_intervals
.
interval_start interval_end
------------------- -------------------
2009-01-01 00:00:00 2009-01-01 23:59:59
2009-01-02 00:00:00 2009-01-02 23:59:59
2009-01-03 00:00:00 2009-01-03 23:59:59
2009-01-04 00:00:00 2009-01-04 23:59:59
2009-01-05 00:00:00 2009-01-05 23:59:59
2009-01-06 00:00:00 2009-01-06 23:59:59
2009-01-07 00:00:00 2009-01-07 23:59:59
2009-01-08 00:00:00 2009-01-08 23:59:59
2009-01-09 00:00:00 2009-01-09 23:59:59
.
call make_intervals('2009-01-01 00:00:00','2009-01-01 02:00:00',10,'MINUTE')
.
select * from time_intervals
.
interval_start interval_end
------------------- -------------------
2009-01-01 00:00:00 2009-01-01 00:09:59
2009-01-01 00:10:00 2009-01-01 00:19:59
2009-01-01 00:20:00 2009-01-01 00:29:59
2009-01-01 00:30:00 2009-01-01 00:39:59
2009-01-01 00:40:00 2009-01-01 00:49:59
2009-01-01 00:50:00 2009-01-01 00:59:59
2009-01-01 01:00:00 2009-01-01 01:09:59
2009-01-01 01:10:00 2009-01-01 01:19:59
2009-01-01 01:20:00 2009-01-01 01:29:59
2009-01-01 01:30:00 2009-01-01 01:39:59
2009-01-01 01:40:00 2009-01-01 01:49:59
2009-01-01 01:50:00 2009-01-01 01:59:59
.
I specified an interval_start and interval_end so you can aggregate the
data timestamps with a "between interval_start and interval_end" type of JOIN.
.
Code for the proc:
.
-- drop procedure make_intervals
.
CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
-- *************************************************************************
-- Procedure: make_intervals()
-- Author: Ron Savage
-- Date: 02/03/2009
--
-- Description:
-- This procedure creates a temporary table named time_intervals with the
-- interval_start and interval_end fields specifed from the startdate and
-- enddate arguments, at intervals of intval (unitval) size.
-- *************************************************************************
declare thisDate timestamp;
declare nextDate timestamp;
set thisDate = startdate;
-- *************************************************************************
-- Drop / create the temp table
-- *************************************************************************
drop temporary table if exists time_intervals;
create temporary table if not exists time_intervals
(
interval_start timestamp,
interval_end timestamp
);
-- *************************************************************************
-- Loop through the startdate adding each intval interval until enddate
-- *************************************************************************
repeat
select
case unitval
when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
when 'SECOND' then timestampadd(SECOND, intval, thisDate)
when 'MINUTE' then timestampadd(MINUTE, intval, thisDate)
when 'HOUR' then timestampadd(HOUR, intval, thisDate)
when 'DAY' then timestampadd(DAY, intval, thisDate)
when 'WEEK' then timestampadd(WEEK, intval, thisDate)
when 'MONTH' then timestampadd(MONTH, intval, thisDate)
when 'QUARTER' then timestampadd(QUARTER, intval, thisDate)
when 'YEAR' then timestampadd(YEAR, intval, thisDate)
end into nextDate;
insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
set thisDate = nextDate;
until thisDate >= enddate
end repeat;
END;
이 게시물 의 맨 아래에있는 유사한 예제 데이터 시나리오에서 SQL Server에 대해 유사한 기능을 구축했습니다.
답변
MSSQL의 경우 이것을 사용할 수 있습니다. 매우 빠릅니다.
이를 테이블 값 함수 또는 저장된 proc에 래핑하고 시작 및 종료 날짜를 변수로 구문 분석 할 수 있습니다.
DECLARE @startDate DATETIME
DECLARE @endDate DATETIME
SET @startDate = '2011-01-01'
SET @endDate = '2011-01-31';
WITH dates(Date) AS
(
SELECT @startdate as Date
UNION ALL
SELECT DATEADD(d,1,[Date])
FROM dates
WHERE DATE < @enddate
)
SELECT Date
FROM dates
OPTION (MAXRECURSION 0)
GO
답변
데이터가없는 날에 대해보고하고 싶다는 점에서 BIRT 보고서와 유사한 문제가있었습니다. 해당 날짜에 대한 항목이 없었기 때문에 가장 쉬운 해결책은 모든 날짜를 저장 한 간단한 테이블을 만들고이를 사용하여 범위를 가져 오거나 조인하여 해당 날짜에 대한 값을 0으로 만드는 것이 었습니다.
앞으로 5 년 동안 테이블이 채워지는지 확인하기 위해 매달 실행되는 작업이 있습니다. 따라서 테이블이 생성됩니다.
create table all_dates (
dt date primary key
);
의심 할 여지없이 다른 DBMS로이 작업을 수행하는 마술적인 까다로운 방법이 있지만 우리는 항상 가장 간단한 솔루션을 선택합니다. 테이블의 저장소 요구 사항은 최소화되어 쿼리를 훨씬 간단하고 이식 할 수 있습니다. 이러한 종류의 솔루션은 데이터에 대한 행당 계산이 필요하지 않기 때문에 성능 관점에서 거의 항상 더 좋습니다.
다른 옵션 (이전에 사용했던)은 모든 날짜에 대해 테이블에 항목이 있는지 확인하는 것입니다. 우리는 주기적으로 테이블을 휩쓸고 존재하지 않는 날짜 및 / 또는 시간에 대한 항목을 추가했습니다. 이것은 귀하의 경우에는 옵션이 아닐 수 있으며 저장된 데이터에 따라 다릅니다.
당신이 경우 실제로 는 유지하는 번거 로움 생각 all_dates
채워 테이블, 저장 프로 시저는 그 날짜를 포함하는 데이터 집합을 반환하는 길을 가야하는 것입니다. 테이블에서 미리 계산 된 데이터를 가져 오는 것보다 호출 될 때마다 범위를 계산해야하기 때문에 거의 확실히 느립니다.
하지만 솔직히 말해서 심각한 데이터 저장 문제없이 1000 년 동안 테이블을 채울 수 있습니다. 16 바이트 (예 : 16 바이트) 날짜 365,000 개, 날짜를 복제하는 인덱스, 안전을 위해 20 % 오버 헤드를 추가 할 수 있습니다. 약 14M [365,000 * 16 * 2 * 1.2 = 14,016,000 바이트]), 사물의 체계에서 아주 작은 표입니다.
답변
다음 과 같이 MySQL의 사용자 변수를 사용할 수 있습니다 .
SET @num = -1;
SELECT DATE_ADD( '2009-01-01', interval @num := @num+1 day) AS date_sequence,
your_table.* FROM your_table
WHERE your_table.other_column IS NOT NULL
HAVING DATE_ADD('2009-01-01', interval @num day) <= '2009-01-13'
@num은 처음 사용할 때 추가하기 때문에 -1입니다. 또한 “HAVING date_sequence”는 사용자 변수가 각 행에 대해 두 번 증가하기 때문에 사용할 수 없습니다.
답변
이 답변 에서 아이디어를 빌려서 0에서 9까지의 테이블을 설정하고이를 사용하여 날짜 목록을 생성 할 수 있습니다.
CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
select adddate('2009-01-01', numlist.id) as `date` from
(SELECT n1.i + n10.i*10 + n100.i*100 AS id
FROM num n1 cross join num as n10 cross join num as n100) as numlist
where adddate('2009-01-01', numlist.id) <= '2009-01-13';
이렇게하면 최대 1000 개의 날짜 목록을 생성 할 수 있습니다. 더 커야하는 경우 내부 쿼리에 다른 교차 조인을 추가 할 수 있습니다.
답변
Access (또는 모든 SQL 언어)
-
이 개 필드가 하나 개의 테이블을 만들고, 우리는이 테이블에 전화 할게
tempRunDates
:
–fieldsfromDate
및toDate
시작 날짜와 종료 날짜가 –Then 삽입 만 한 기록을. -
다른 테이블 만들기 :-
Time_Day_Ref
날짜 목록을이 테이블로 가져옵니다 (Excel에서 목록 만들기는 쉽습니다).
-제 경우 필드 이름은Greg_Dt
그레고리 안 날짜의 경우
-2009 년 1 월 1 일부터 2020 년 1 월 1 일까지 목록을 작성했습니다. -
쿼리를 실행합니다.
SELECT Time_Day_Ref.GREG_DT FROM tempRunDates, Time_Day_Ref WHERE Time_Day_Ref.greg_dt>=tempRunDates.fromDate And greg_dt<=tempRunDates.toDate;
쉬운!
답변
일반적으로이 목적을 위해 보통 보관하는 보조 숫자 테이블을 사용하며 이에 대한 약간의 변형이 있습니다.
SELECT *
FROM (
SELECT DATEADD(d, number - 1, '2009-01-01') AS dt
FROM Numbers
WHERE number BETWEEN 1 AND DATEDIFF(d, '2009-01-01', '2009-01-13') + 1
) AS DateRange
LEFT JOIN YourStuff
ON DateRange.dt = YourStuff.DateColumn
테이블 반환 함수 등의 변형을 보았습니다.
영구 날짜 목록을 유지할 수도 있습니다. 데이터웨어 하우스와 하루 중 시간 목록에 있습니다.