SQL을 사용하여 날짜 범위 생성
날짜 매개 변수를 함수에 넣는 SQL 쿼리가 있으며, 이를 작년 매일 실행해야 합니다.
지난 365일 목록을 생성하여 이를 위해 스트레이트업 SQL을 사용할 수 있도록 하려면 어떻게 해야 합니까?
분명히 목록 0을 생성하고 있습니다.364도 잘 될 거야. 난 항상 할 수 있으니까:
SELECT SYSDATE - val FROM (...);
큰 테이블이나 ALL_OBJECTs 테이블을 사용할 필요가 없습니다.
SELECT TRUNC (SYSDATE - ROWNUM) dt
FROM DUAL CONNECT BY ROWNUM < 366
효과가 있을 거야
최근에 비슷한 문제가 있어서 다음과 같은 간단한 질문으로 해결했습니다.
SELECT
(to_date(:p_to_date,'DD-MM-YYYY') - level + 1) AS day
FROM
dual
CONNECT BY LEVEL <= (to_date(:p_to_date,'DD-MM-YYYY') - to_date(:p_from_date,'DD-MM-YYYY') + 1);
예
SELECT
(to_date('01-05-2015','DD-MM-YYYY') - level + 1) AS day
FROM
dual
CONNECT BY LEVEL <= (to_date('01-05-2015','DD-MM-YYYY') - to_date('01-04-2015','DD-MM-YYYY') + 1);
결과
01-05-2015 00:00:00
30-04-2015 00:00:00
29-04-2015 00:00:00
28-04-2015 00:00:00
27-04-2015 00:00:00
26-04-2015 00:00:00
25-04-2015 00:00:00
24-04-2015 00:00:00
23-04-2015 00:00:00
22-04-2015 00:00:00
21-04-2015 00:00:00
20-04-2015 00:00:00
19-04-2015 00:00:00
18-04-2015 00:00:00
17-04-2015 00:00:00
16-04-2015 00:00:00
15-04-2015 00:00:00
14-04-2015 00:00:00
13-04-2015 00:00:00
12-04-2015 00:00:00
11-04-2015 00:00:00
10-04-2015 00:00:00
09-04-2015 00:00:00
08-04-2015 00:00:00
07-04-2015 00:00:00
06-04-2015 00:00:00
05-04-2015 00:00:00
04-04-2015 00:00:00
03-04-2015 00:00:00
02-04-2015 00:00:00
01-04-2015 00:00:00
SELECT (sysdate-365 + (LEVEL -1)) AS DATES
FROM DUAL connect by level <=( sysdate-(sysdate-365))
sysdate 및 sysdate-date 대신 'from' 및 'to' 날짜가 대체될 경우 출력은 에서 날짜까지의 날짜 범위가 됩니다.
Oracle에서 자주 사용되는 방법은 다음과 같습니다.
select trunc(sysdate)-rn
from
( select rownum rn
from dual
connect by level <= 365)
/
개인적으로는 어플리케이션에 날짜 리스트가 필요한 경우 표를 작성하거나 100만 개까지의 정수가 포함된 표를 만듭니다.이러한 일에는 사용할 수 있습니다.
데이터 사전 개체에 대한 기존의 큰 테이블이나 복잡한 시스템 뷰에 의존하지 않습니다.
SELECT c1 from dual
MODEL DIMENSION BY (1 as rn) MEASURES (sysdate as c1)
RULES ITERATE (365)
(c1[ITERATION_NUMBER]=SYSDATE-ITERATION_NUMBER)
order by 1
1년 반 정도 늦었지만, 후세를 위해 Teradata를 위한 버전을 소개합니다.
SELECT calendar_date
FROM SYS_CALENDAR.Calendar
WHERE SYS_CALENDAR.Calendar.calendar_date between '2010-01-01' (date) and '2010-01-03' (date)
날짜 범위는 1996년 12월 31일부터 2020년 12월 31일까지입니다.
SELECT dt, to_char(dt, 'MM/DD/YYYY') as date_name,
EXTRACT(year from dt) as year,
EXTRACT(year from fiscal_dt) as fiscal_year,
initcap(to_char(dt, 'MON')) as month,
to_char(dt, 'YYYY') || ' ' || initcap(to_char(dt, 'MON')) as year_month,
to_char(fiscal_dt, 'YYYY') || ' ' || initcap(to_char(dt, 'MON')) as fiscal_year_month,
EXTRACT(year from dt)*100 + EXTRACT(month from dt) as year_month_id,
EXTRACT(year from fiscal_dt)*100 + EXTRACT(month from fiscal_dt) as fiscal_year_month_id,
to_char(dt, 'YYYY') || ' Q' || to_char(dt, 'Q') as quarter,
to_char(fiscal_dt, 'YYYY') || ' Q' || to_char(fiscal_dt, 'Q') as fiscal_quarter
--, EXTRACT(day from dt) as day_of_month, to_char(dt, 'YYYY-WW') as week_of_year, to_char(dt, 'D') as day_of_week
FROM (
SELECT dt, add_months(dt, 6) as fiscal_dt --starts July 1st
FROM (
SELECT TO_DATE('12/31/1996', 'mm/dd/yyyy') + ROWNUM as dt
FROM DUAL CONNECT BY ROWNUM < 366 * 30 --30 years
)
WHERE dt <= TO_DATE('12/31/2020', 'mm/dd/yyyy')
)
아하하, 이렇게 하기 위해 제가 생각해낸 재미있는 방법이 있습니다.
select SYSDATE - ROWNUM
from shipment_weights sw
where ROWNUM < 365;
여기서 shippment_timeout은 큰 테이블입니다.
저도 같은 요구였습니다.이것만 사용하겠습니다.사용자는 일정 범위를 제한하는 일수를 입력합니다.
SELECT DAY, offset
FROM (SELECT to_char(SYSDATE, 'DD-MON-YYYY') AS DAY, 0 AS offset
FROM DUAL
UNION ALL
SELECT to_char(SYSDATE - rownum, 'DD-MON-YYYY'), rownum
FROM all_objects d)
where offset <= &No_of_days
나는 위의 결과 세트를 운전 뷰로 사용한다.LEFT OUTER JOIN날짜가 있는 테이블을 포함하는 다른 보기와 함께.
6개월 후 일주일 후
SELECT (date'2015-08-03' + (LEVEL-1)) AS DATES
FROM DUAL
where ROWNUM < 8
connect by level <= (sysdate-date'2015-08-03');
ROWNUM을 생략하면 값에 관계없이 50행만 얻을 수 있습니다.
늦더라도 안 하느니보다는 낫다.다음은 (이 게시물을 읽은 후) (a) 금월 1일 ~ 오늘까지의 날짜 목록과 (b) 지난 2개월 동안의 모든 날짜를 포함하는 날짜 목록을 반환하기 위한 방법입니다.
select (sysdate +1 - rownum) dt
from dual
connect by rownum <= (sysdate - add_months(sysdate - extract(day from sysdate),-2));
"-2"는 포함할 전체 달의 수입니다.예를 들어, 7월 10일에 이 SQL은 5월 1일부터 7월 10일까지의 모든 날짜 목록을 반환합니다. 즉, 2개의 완전한 이전 달과 현재의 부분 달입니다.
오늘부터 365일 후를 얻는 또 다른 간단한 방법은 다음과 같습니다.
SELECT (TRUNC(sysdate) + (LEVEL-366)) AS DATE_ID
FROM DUAL connect by level <=( (sysdate)-(sysdate-366));
SQL Server, Oracle 또는 MySQL에서 작동해야 하는 몇 가지 코드는 다음과 같습니다.
SELECT current_timestamp - CAST(d1.digit + d2.digit + d3.digit as int)
FROM
(
SELECT digit
FROM
(
select '1' as digit
union select '2'
union select '3'
union select '4'
union select '5'
union select '6'
union select '7'
union select '8'
union select '9'
union select '0'
) digits
) d1
CROSS JOIN
(
SELECT digit
FROM
(
select '1' as digit
union select '2'
union select '3'
union select '4'
union select '5'
union select '6'
union select '7'
union select '8'
union select '9'
union select '0'
) digits
) d2
CROSS JOIN
(
SELECT digit
FROM
(
select '1' as digit
union select '2'
union select '3'
union select '4'
union select '5'
union select '6'
union select '7'
union select '8'
union select '9'
union select '0'
) digits
) d3
WHERE CAST(d1.digit + d2.digit + d3.digit as int) < 365
ORDER BY d1.digit, d2.digit, d3.digit -- order not really needed here
숫자 테이블을 재사용할 수 있는 교차 플랫폼 구문을 제공할 수 있다면 보너스 포인트입니다.
스케줄 앱에서 자주 하는 일이라 파이프라인 테이블 함수를 만들었습니다.가끔 며칠, 몇 시간, 15분씩 시간이 필요할 때가 있어요.코드가 패키지에 포함되어 있기 때문에 이 기능은 제가 사용하는 기능과 완전히 다릅니다.하지만 여기서는 2020년 1월 1일부터 2020년 1월 10일까지의 날짜를 얻을 수 있습니다.
SELECT
days.date_time
FROM
table(between_times(TO_DATE('2020-01-01'),TO_DATE('2020-01-10'),(60*24), 'Y')) days
파이프라인 기능:
function between_times(i_start_time TIMESTAMP, i_end_time TIMESTAMP, i_interval_in_minutes NUMBER, include_end_time VARCHAR2 := 'N')
RETURN DateTableType PIPELINED
AS
time_counter TIMESTAMP := i_start_time;
BEGIN
IF i_start_time IS NULL OR i_end_time IS NULL or i_start_time > i_end_time OR i_interval_in_minutes IS NULL OR
i_interval_in_minutes <= 0 THEN
RETURN;
END IF;
LOOP
-- by default does not include end time
if (include_end_time = 'Y') THEN
exit when time_counter > i_end_time;
ELSE
exit when time_counter >= i_end_time;
END IF;
pipe row(DateType( time_counter ));
time_counter := time_counter + i_interval_in_minutes/(60*24);
END LOOP;
EXCEPTION WHEN NO_DATA_NEEDED THEN NULL;
END;
WITH Date_Table (Dates, Heading) AS -- Using Oracle SQL
(SELECT TRUNC(SYSDATE) Dates, ' Start' as Heading FROM dual
UNION ALL
SELECT TRUNC(DATES-1) , ' Inside recursion' as Heading FROM Date_Table
WHERE Dates > sysdate-365 ) -- Go back one year
SELECT TO_CHAR(Dates,'MM/DD/YYYY')
FROM Date_Table
ORDER BY Dates DESC;
숫자 테이블을 재사용할 수 있는 답변은 없지만 SQL Server에서 작동하며 좀 더 빠른 코드 샘플이 있습니다.
print("code sample");
select top 366 current_timestamp - row_number() over( order by l.A * r.A) as DateValue
from (
select 1 as A union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10 union
select 11 union
select 12 union
select 13 union
select 14 union
select 15 union
select 16 union
select 17 union
select 18 union
select 19 union
select 20 union
select 21
) l
cross join (
select 1 as A union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10 union
select 11 union
select 12 union
select 13 union
select 14 union
select 15 union
select 16 union
select 17 union
select 18
) r
print("code sample");
이 쿼리는 현재 4000일 미래 및 5000일 과거 날짜 목록을 생성합니다(http://blogs.x2line.com/al/articles/207.aspx)에서 영감을 받았습니다.
SELECT * FROM (SELECT
(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
n4.num * 1000 -
n3.num * 100 -
n2.num * 10 -
n1.num) AS Date,
year(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
n4.num * 1000 -
n3.num * 100 -
n2.num * 10 -
n1.num) as Year,
month(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
n4.num * 1000 -
n3.num * 100 -
n2.num * 10 -
n1.num) as Month,
day(CONVERT(SMALLDATETIME, CONVERT(CHAR,GETDATE() ,103)) + 4000 -
n4.num * 1000 -
n3.num * 100 -
n2.num * 10 -
n1.num) as Day
FROM (SELECT 0 AS num union ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9) n1
,(SELECT 0 AS num UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9) n2
,(SELECT 0 AS num union ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9) n3
,(SELECT 0 AS num UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8) n4
) GenCalendar ORDER BY 1
언급URL : https://stackoverflow.com/questions/418318/generate-a-range-of-dates-using-sql
'programing' 카테고리의 다른 글
| angular 템플릿의 배열 값을 확인하시겠습니까? (0) | 2023.02.23 |
|---|---|
| jQuery ajax 성공 콜백 함수 정의 (0) | 2023.02.23 |
| Python json.loads의 제어 문자가 잘못되었습니다. (0) | 2023.02.23 |
| 단일 파일에 대해 더 예쁜 파일 사용 안 함 (0) | 2023.02.23 |
| grunt 서버를 사용하여 모든 요청을 루트 URL로 리다이렉트하려면 어떻게 해야 합니까? (0) | 2023.02.23 |