복붙노트

[SQL] 날짜 범위에서 일을 생성

SQL

날짜 범위에서 일을 생성

내가 좋아하는 쿼리를 실행하고 싶습니다

select ... as days where `date` is between '2010-01-20' and '2010-01-24'

그리고 데이터를 같이 반환 :

days
----------
2010-01-20
2010-01-21
2010-01-22
2010-01-23
2010-01-24

해결법

  1. ==============================

    1.이 솔루션은 더 루프, 절차, 또는 임시 테이블을 사용하지 않습니다. 하위 쿼리는 지난 만일을 위해 날짜를 생성하고, 멀리 뒤로 또는 앞으로 당신이 원하는대로 갈 수 있도록 확장 할 수있다.

    이 솔루션은 더 루프, 절차, 또는 임시 테이블을 사용하지 않습니다. 하위 쿼리는 지난 만일을 위해 날짜를 생성하고, 멀리 뒤로 또는 앞으로 당신이 원하는대로 갈 수 있도록 확장 할 수있다.

    select a.Date 
    from (
        select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY as Date
        from (select 0 as a 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) as a
        cross join (select 0 as a 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) as b
        cross join (select 0 as a 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) as c
        cross join (select 0 as a 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) as d
    ) a
    where a.Date between '2010-01-20' and '2010-01-24' 
    

    산출:

    Date
    ----------
    2010-01-24
    2010-01-23
    2010-01-22
    2010-01-21
    2010-01-20
    

    성능에 대한 참고 사항

    여기에 그것을 밖으로 테스트, 성능은 놀라 울 정도로 좋은 : 위의 쿼리가 0.0009 초 걸립니다.

    우리는 확장 할 경우 하위 쿼리는 약 생성합니다. 10 개 숫자 (날짜 때문에 274에 대한 년 가치가), 그것은 0.0458 초에서 실행됩니다.

    덧붙여,이 사소한 조정에 대부분의 데이터베이스에서 작동하는 매우 휴대용 기술이다.

    천일 반환 SQL 바이올린 예

  2. ==============================

    2.여기서 뷰를 이용하여 다른 변형 예이다 :

    여기서 뷰를 이용하여 다른 변형 예이다 :

    CREATE VIEW digits AS
      SELECT 0 AS digit 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;
    
    CREATE VIEW numbers AS
      SELECT
        ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number
      FROM
        digits as ones,
        digits as tens,
        digits as hundreds,
        digits as thousands;
    
    CREATE VIEW dates AS
      SELECT
        SUBDATE(CURRENT_DATE(), number) AS date
      FROM
        numbers;
    

    그리고 당신은 단순히 (이 얼마나 우아 참조?) 할 수 있습니다 :

    SELECT
      date
    FROM
      dates
    WHERE
      date BETWEEN '2010-01-20' AND '2010-01-24'
    ORDER BY
      date
    

    최신 정보

    그것은 당신이 단지 현재 날짜부터 시작 날짜를지나 생성 할 수 있다는 것을 주목할 필요가있다. 당신이 날짜 범위의 모든 종류를 생성 할 경우 (과거, 미래, 그리고 그 사이에), 대신이보기를 사용해야합니다 :

    CREATE VIEW dates AS
      SELECT
        SUBDATE(CURRENT_DATE(), number) AS date
      FROM
        numbers
      UNION ALL
      SELECT
        ADDDATE(CURRENT_DATE(), number + 1) AS date
      FROM
        numbers;
    
  3. ==============================

    3.허용 대답은 (또는 "A"근처에 구문 오류) PostgreSQL을위한 일을하지 않았다.

    허용 대답은 (또는 "A"근처에 구문 오류) PostgreSQL을위한 일을하지 않았다.

    당신은 PostgreSQL의에서이 작업을 수행하는 방법은 generate_series 기능, 즉를 사용하는 것입니다 :

    SELECT day::date
    FROM generate_series('2010-01-20', '2010-01-24', INTERVAL '1 day') day;
    
        day
    ------------
     2010-01-20
     2010-01-21
     2010-01-22
     2010-01-23
     2010-01-24
    (5 rows)
    
  4. ==============================

    4.재귀 공통 테이블 식 (CTE)를 사용하면 다음 선택, 날짜 목록을 생성 할 수 있습니다. 이것은 단지 가능성을 보여 있도록 분명히 당신은 일반적으로, 삼백 만 날짜를 만들려하지 않을 것입니다. 당신은 단순히 CTE 내부의 날짜 범위를 제한하고 CTE를 사용하여 select 문에서 where 절을 생략 할 수있다.

    재귀 공통 테이블 식 (CTE)를 사용하면 다음 선택, 날짜 목록을 생성 할 수 있습니다. 이것은 단지 가능성을 보여 있도록 분명히 당신은 일반적으로, 삼백 만 날짜를 만들려하지 않을 것입니다. 당신은 단순히 CTE 내부의 날짜 범위를 제한하고 CTE를 사용하여 select 문에서 where 절을 생략 할 수있다.

    with [dates] as (
        select convert(datetime, '1753-01-01') as [date] --start
        union all
        select dateadd(day, 1, [date])
        from [dates]
        where [date] < '9999-12-31' --end
    )
    select [date]
    from [dates]
    where [date] between '2013-01-01' and '2013-12-31'
    option (maxrecursion 0)
    

    마이크로 소프트 SQL 서버 2005, 모든 가능한 날짜의 CTE 목록을 생성하는 1시 8분했다. 생성 백년은 초 미만했다.

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

    5.MSSQL 쿼리

    MSSQL 쿼리

    select datetable.Date 
    from (
        select DATEADD(day,-(a.a + (10 * b.a) + (100 * c.a)),getdate()) AS Date
        from (select 0 as a 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) as a
    
        cross join (select 0 as a 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) as b
    
        cross join (select 0 as a 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) as c
    ) datetable
    where datetable.Date between '2014-01-20' and '2014-01-24' 
    order by datetable.Date DESC
    

    산출

    Date
    -----
    2014-01-23 12:35:25.250
    2014-01-22 12:35:25.250
    2014-01-21 12:35:25.250
    2014-01-20 12:35:25.250
    
  6. ==============================

    6.루프 / 커서없이 이렇게하는 오래된 학교의 솔루션은 값이 1에서 시작하는 단일 정수 열이있는 NUMBERS 테이블을 작성하는 것입니다.

    루프 / 커서없이 이렇게하는 오래된 학교의 솔루션은 값이 1에서 시작하는 단일 정수 열이있는 NUMBERS 테이블을 작성하는 것입니다.

    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    당신은 당신의 요구를 충당하기에 충분한 기록과 함께 테이블을 채울 필요가 :

    INSERT INTO NUMBERS (id) VALUES (NULL);
    

    당신이 NUMBERS 테이블이 있으면, 당신은 사용할 수 있습니다 :

    SELECT x.start_date + INTERVAL n.id-1 DAY
      FROM NUMBERS n
      JOIN (SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d') AS start_date 
              FROM DUAL) x
     WHERE x.start_date + INTERVAL n.id-1 DAY <= '2010-01-24'
    

    절대 낮은 기술 솔루션은 다음과 같습니다

    SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d')
     FROM DUAL
    UNION ALL
    SELECT STR_TO_DATE('2010-01-21', '%Y-%m-%d')
     FROM DUAL
    UNION ALL
    SELECT STR_TO_DATE('2010-01-22', '%Y-%m-%d')
     FROM DUAL
    UNION ALL
    SELECT STR_TO_DATE('2010-01-23', '%Y-%m-%d')
     FROM DUAL
    UNION ALL
    SELECT STR_TO_DATE('2010-01-24', '%Y-%m-%d')
     FROM DUAL
    

    LEFT하기 위해 날짜 또는 숫자의 목록을 생성의 정보는 다음의 제품에에 가입하세요. 격차가 존재하는 곳 널 (null) 값이 분명 할 것이다 - 데이터에 차이가있는 위치를 좌두고 순차적 데이터 목록에 합류하기 때문에이하기 위해, 볼 것입니다.

  7. ==============================

    7.액세스 2010 - 여러 단계가 필요합니다; 나는 위의 게시와 같은 패턴을 따라,하지만 난 Access에서 다른 사람을 도울 수 있다고 생각. 나를 위해 좋은 일했다, 나는 날짜의 시드 테이블을 계속해야하지 않았다.

    액세스 2010 - 여러 단계가 필요합니다; 나는 위의 게시와 같은 패턴을 따라,하지만 난 Access에서 다른 사람을 도울 수 있다고 생각. 나를 위해 좋은 일했다, 나는 날짜의 시드 테이블을 계속해야하지 않았다.

    DUAL (오라클 DUAL 테이블이 작동하는 방식과 유사)라는 테이블을 만듭니다

    "ZeroThru9Q"라는 이름의 쿼리를 만듭니다; 수동으로 다음 구문을 입력 :

    SELECT 0 AS a
    FROM dual
    UNION ALL
    SELECT 1
    FROM dual
    UNION ALL
    SELECT 2
    FROM dual
    UNION ALL
    SELECT 3
    FROM dual
    UNION ALL
    SELECT 4
    FROM dual
    UNION ALL
    SELECT 5
    FROM dual
    UNION ALL
    SELECT 6
    FROM dual
    UNION ALL
    SELECT 7
    FROM dual
    UNION ALL
    SELECT 8
    FROM dual
    UNION ALL
    SELECT 9
    FROM dual;
    

    (오늘 이전 날짜에 대해) "TodayMinus1KQ"라는 쿼리를 만듭니다; 수동으로 다음 구문을 입력 :

    SELECT date() - (a.a + (10 * b.a) + (100 * c.a)) AS MyDate
    FROM
      (SELECT *
       FROM ZeroThru9Q) AS a,
    
      (SELECT *
       FROM ZeroThru9Q) AS b,
    
      (SELECT *
       FROM ZeroThru9Q) AS c
    

    (오늘 이후 날짜에 대해) "TodayPlus1KQ"라는 쿼리를 만듭니다; 수동으로 다음 구문을 입력 :

    SELECT date() + (a.a + (10 * b.a) + (100 * c.a)) AS MyDate
    FROM
      (SELECT *
       FROM ZeroThru9Q) AS a,
    
      (SELECT *
       FROM ZeroThru9Q) AS b,
    
      (SELECT *
       FROM ZeroThru9Q) AS c;
    

    노조 "TodayPlusMinus1KQ"라는 쿼리 (날짜 +/- 천일에 대한) 만들기 :

    SELECT MyDate
    FROM TodayMinus1KQ
    UNION
    SELECT MyDate
    FROM TodayPlus1KQ;
    

    이제 쿼리를 사용할 수 있습니다 :

    SELECT MyDate
    FROM TodayPlusMinus1KQ
    WHERE MyDate BETWEEN #05/01/2014# and #05/30/2014#
    
  8. ==============================

    8.절차 + 임시 테이블 :

    절차 + 임시 테이블 :

    DELIMITER $$
    
    CREATE DEFINER=`root`@`localhost` PROCEDURE `days`(IN dateStart DATE, IN dateEnd DATE)
    BEGIN
    
        CREATE TEMPORARY TABLE IF NOT EXISTS date_range (day DATE);
    
        WHILE dateStart <= dateEnd DO
          INSERT INTO date_range VALUES (dateStart);
          SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);
        END WHILE;
    
        SELECT * FROM date_range;
        DROP TEMPORARY TABLE IF EXISTS date_range;
    
    END
    
  9. ==============================

    9.들으 Pentium10 - 당신은 나에 유래 :)에 가입했다 - 이 MSACCESS 내 이식 - 그것은 모든 버전에서 작동 거라고 생각 :

    들으 Pentium10 - 당신은 나에 유래 :)에 가입했다 - 이 MSACCESS 내 이식 - 그것은 모든 버전에서 작동 거라고 생각 :

    SELECT date_value
    FROM (SELECT a.espr1+(10*b.espr1)+(100*c.espr1) AS integer_value,
    dateadd("d",integer_value,dateserial([start_year], [start_month], [start_day])) as date_value
    FROM (select * from 
        (
        select top 1 "0" as espr1 from MSysObjects
        union all
        select top 1 "1" as espr2 from MSysObjects
        union all
        select top 1 "2" as espr3 from MSysObjects
        union all
        select top 1 "3" as espr4 from MSysObjects
        union all
        select top 1 "4" as espr5 from MSysObjects
        union all
        select top 1 "5" as espr6 from MSysObjects
        union all
        select top 1 "6" as espr7 from MSysObjects
        union all
        select top 1 "7" as espr8 from MSysObjects
        union all
        select top 1 "8" as espr9 from MSysObjects
        union all
        select top 1 "9" as espr9 from MSysObjects
        ) as a,
        (
        select top 1 "0" as espr1 from MSysObjects
        union all
        select top 1 "1" as espr2 from MSysObjects
        union all
        select top 1 "2" as espr3 from MSysObjects
        union all
        select top 1 "3" as espr4 from MSysObjects
        union all
        select top 1 "4" as espr5 from MSysObjects
        union all
        select top 1 "5" as espr6 from MSysObjects
        union all
        select top 1 "6" as espr7 from MSysObjects
        union all
        select top 1 "7" as espr8 from MSysObjects
        union all
        select top 1 "8" as espr9 from MSysObjects
        union all
        select top 1 "9" as espr9 from MSysObjects
        ) as b,
        (
        select top 1 "0" as espr1 from MSysObjects
        union all
        select top 1 "1" as espr2 from MSysObjects
        union all
        select top 1 "2" as espr3 from MSysObjects
        union all
        select top 1 "3" as espr4 from MSysObjects
        union all
        select top 1 "4" as espr5 from MSysObjects
        union all
        select top 1 "5" as espr6 from MSysObjects
        union all
        select top 1 "6" as espr7 from MSysObjects
        union all
        select top 1 "7" as espr8 from MSysObjects
        union all
        select top 1 "8" as espr9 from MSysObjects
        union all
        select top 1 "9" as espr9 from MSysObjects
        ) as c   
    )  as d) 
    WHERE date_value 
    between dateserial([start_year], [start_month], [start_day]) 
    and dateserial([end_year], [end_month], [end_day]);
    

    참조으로 MSysObjects 단지 '원인 액세스 필요 테이블 countin'절에서 적어도 1 명 기록 - 할 것 적어도 한 기록을 가진 모든 테이블을.

  10. ==============================

    10.이 시도.

    이 시도.

    SELECT TO_DATE('20160210','yyyymmdd') - 1 + LEVEL AS start_day 
    from DUAL
    connect by level <= (TO_DATE('20160228','yyyymmdd') + 1) - TO_DATE('20160210','yyyymmdd') ;
    
  11. ==============================

    11.만약 당신이 몇 일 더 다음이 필요합니다, 당신은 테이블이 필요합니다.

    만약 당신이 몇 일 더 다음이 필요합니다, 당신은 테이블이 필요합니다.

    MySQL의에서 날짜 범위를 만들기

    그때,

    select from days.day, count(mytable.field) as fields from days left join mytable on day=date where date between x and y;
    
  12. ==============================

    12.진술 (또는 적어도 언급) 이미 주어진 멋진 답변의 대부분에 당신이 작업을하려면 숫자의 집합을 일단이 문제는 쉽게 해결된다.

    진술 (또는 적어도 언급) 이미 주어진 멋진 답변의 대부분에 당신이 작업을하려면 숫자의 집합을 일단이 문제는 쉽게 해결된다.

    참고 : 다음은 T-SQL이지만 단순히 이미 큰에서 여기 인터넷에서 언급 한 일반적인 개념의 내 특정 구현입니다. 선택의 방언에 코드를 변환하는 비교적 간단해야한다.

    어떻게? 이 쿼리를 고려 :

    SELECT DATEADD(d, N, '0001-01-22')
    FROM Numbers -- A table containing the numbers 0 through N
    WHERE N <= 5;
    

    1/27/0001을 매우 간단하다 - 위는 날짜 범위 1/22/0001을 생산하고 있습니다. 시작 0001-01-22의 날짜와 우리는이 두 가지 정보를 결합하면 우리는 분명히 우리의 종료 날짜가 5의 오프셋 (offset) : 위의 쿼리 정보의 2 가지 핵심이있다. 따라서, 범위를 생성하는 단계과 같이 분해 될 수 있으며, 두 날짜 부여 :

    이 두 가지 방법을 결합하면 우리의 문제를 해결합니다 :

    DECLARE @date1 DATE = '9001-11-21';
    DECLARE @date2 DATE = '9001-11-23';
    
    SELECT D = DATEADD(d, N, @date1)
    FROM (
        SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
        FROM (SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A') S
    ) Numbers
    WHERE N <= ABS(DATEDIFF(d, @date1, @date2));
    

    위의 예는 끔찍한 코드를 제외한 모든 함께 오는 방법을 보여줍니다.

    더 재미있는

    나는 두 TVFs로 로직을 캡슐화 그래서 나는 이런 종류의 일을 많이 할 필요가있다. 먼저 숫자 범위를 생성하고, 두 번째는 날짜 범위를 생성하기 위해이 기능을 사용한다. 수학 문제가되지 않는 입력 순서를 보장하는 것입니다 내가 원했기 때문에 GenerateRangeSmallInt에서 사용할 수의 전체 범위를 사용합니다.

    다음 함수는 CPU 시간 16ms 65536 날짜의 최대 범위를 반환 ~ 소요됩니다.

    CREATE FUNCTION dbo.GenerateRangeDate (   
        @date1 DATE,   
        @date2 DATE   
    )   
    RETURNS TABLE
    WITH SCHEMABINDING   
    AS   
    RETURN (
        SELECT D = DATEADD(d, N + 32768, CASE WHEN @date1 <= @date2 THEN @date1 ELSE @date2 END)
        FROM dbo.GenerateRangeSmallInt(-32768, ABS(DATEDIFF(d, @date1, @date2)) - 32768)
    );
    
    GO
    
    CREATE FUNCTION dbo.GenerateRangeSmallInt (
        @num1 SMALLINT = -32768
      , @num2 SMALLINT = 32767
    )
    RETURNS TABLE
    WITH SCHEMABINDING
    AS
    RETURN (
        WITH Numbers(N) AS (
            SELECT N FROM(VALUES
                (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
              , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
            ) V (N)
        )
        SELECT TOP(ABS(CAST(@num1 AS INT) - CAST(@num2 AS INT)) + 1)
               N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN @num1 <= @num2 THEN @num1 ELSE @num2 END - 1
        FROM Numbers A
           , Numbers B
    );
    
  13. ==============================

    13.다음 예는

    다음 예는

    우리는 하나 개의 테이블에 날짜가

    테이블 이름 : "testdate"

    STARTDATE   ENDDATE
    10/24/2012  10/24/2012
    10/27/2012  10/29/2012
    10/30/2012  10/30/2012
    

    결과를 필요 :

    STARTDATE
    10/24/2012
    10/27/2012
    10/28/2012
    10/29/2012
    10/30/2012
    

    해결책:

    WITH CTE AS
      (SELECT DISTINCT convert(varchar(10),StartTime, 101) AS StartTime,
                       datediff(dd,StartTime, endTime) AS diff
       FROM dbo.testdate
       UNION ALL SELECT StartTime,
                        diff - 1 AS diff
       FROM CTE
       WHERE diff<> 0)
    SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime
    FROM CTE
    

    설명 : CTE 재귀 쿼리 설명

    예를 들면

    STARTDATE   DIFF
    10/24/2012  0
    10/27/2012  0
    10/27/2012  1
    10/27/2012  2
    10/30/2012  0
    

    사양 결과

    STARTDATE       Specification
    10/24/2012  --> From Record 1
    10/27/2012  --> From Record 2
    10/27/2012  --> From Record 2
    10/27/2012  --> From Record 2
    10/30/2012  --> From Record 3
    

    결과

    STARTDATE
    10/24/2012
    10/27/2012
    10/28/2012
    10/29/2012
    10/30/2012
    
  14. ==============================

    14.허용 대답, 같은 생각보다 짧은 :

    허용 대답, 같은 생각보다 짧은 :

    (SELECT TRIM('2016-01-05' + INTERVAL a + b DAY) date
    FROM
    (SELECT 0 a UNION SELECT 1 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 ) d,
    (SELECT 0 b UNION SELECT 10 UNION SELECT 20
    UNION SELECT 30 UNION SELECT 40) m
    WHERE '2016-01-05' + INTERVAL a + b DAY  <=  '2016-01-21')
    
  15. ==============================

    15.(MySQL은 뷰에서 중첩 SELECT 문을 지원하지 않음) 저장된보기로이 원하는 사람들을위한 :

    (MySQL은 뷰에서 중첩 SELECT 문을 지원하지 않음) 저장된보기로이 원하는 사람들을위한 :

    create view zero_to_nine as
        select 0 as n 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;
    
    create view date_range as
        select curdate() - INTERVAL (a.n + (10 * b.n) + (100 * c.n)) DAY as date
        from zero_to_nine as a
        cross join zero_to_nine as b
        cross join zero_to_nine as c;
    

    당신은 할 수있다

    select * from date_range
    

    얻을 수

    date
    ---
    2017-06-06
    2017-06-05
    2017-06-04
    2017-06-03
    2017-06-02
    ...
    
  16. ==============================

    16.당신은 A 날짜 범위를 좀하고 싶습니다.

    당신은 A 날짜 범위를 좀하고 싶습니다.

    귀하의 예제에서 당신은 '2010-01-24'을 '2010-01-20'사이의 날짜를 얻고 싶습니다

    가능한 해결책:

     select date_add('2010-01-20', interval row day) from
     ( 
        SELECT @row := @row + 1 as row FROM 
        (select 0 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 6 union all select 7 union all select 8 union all select 9) t,
        (select 0 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 6 union all select 7 union all select 8 union all select 9) t2, 
        (select 0 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 6 union all select 7 union all select 8 union all select 9) t3, 
        (select 0 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 6 union all select 7 union all select 8 union all select 9) t4, 
        (SELECT @row:=-1) r
     ) sequence
     where date_add('2010-01-20', interval row day) <= '2010-01-24'
    

    설명

    MySQL의는 DATE_ADD 기능 정도가

    select date_add('2010-01-20', interval 1 day)
    

    당신에게 줄 것이다

    2010-01-21
    

    DATEDIFF 함수는이를 반복해야 할 것 자주 알려 것

    select datediff('2010-01-24', '2010-01-20')
    

    이는 반환

     4
    

    날짜 범위에서 날짜 목록을 얻기 정수 숫자의 시퀀스를 생성 귀결은 MySQL은 정수 시퀀스를 생성 참조

    여기서 가장 upvoted 대답은 기본으로 https://stackoverflow.com/a/2652051/1497139와 유사한 접근 방식을 촬영하고있다 :

    SELECT @row := @row + 1 as row FROM 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
    (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
    (SELECT @row:=0) r
    limit 4
    

    에서 발생할 것이다

    row
    1.0
    2.0
    3.0
    4.0
    

    행은 이제 주어진 시작 날짜에서 날짜 목록을 만들 수 있습니다. 우리가 -1 행로 시작하는 시작 날짜를 포함하려면;

    select date_add('2010-01-20', interval row day) from
     ( 
        SELECT @row := @row + 1 as row FROM 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
        (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
        (SELECT @row:=-1) r
     ) sequence
     where date_add('2010-01-20', interval row day) <= '2010-01-24'
    
  17. ==============================

    17.MariaDB에서> = 10.3와 MySQL> = 8.0 새로운 재귀 (공통 테이블 식) 기능을 사용하여 우아한 솔루션입니다.

    MariaDB에서> = 10.3와 MySQL> = 8.0 새로운 재귀 (공통 테이블 식) 기능을 사용하여 우아한 솔루션입니다.

    WITH RECURSIVE t as (
        select '2019-01-01' as dt
      UNION
        SELECT DATE_ADD(t.dt, INTERVAL 1 DAY) FROM t WHERE DATE_ADD(t.dt, INTERVAL 1 DAY) <= '2019-04-30'
    )
    select * FROM t;
    

    위의 반환 '2019년 1월 1일'와 '2019년 4월 30일'사이의 날짜의 테이블. 그것은 상당히 빠릅니다. 날짜 1000 년 가치 (~ 365,000일)를 반환하는 내 컴퓨터에서 400ms 일 정도 걸립니다.

  18. ==============================

    18.그것은 즉시이 날짜 생성과 좋은 아이디어입니다. 그러나, 나는 다음과 같은 해결책을 종료 한 때문에 자신을 편안 매우 넓은 범위로이 일을 생각하지 않습니다 :

    그것은 즉시이 날짜 생성과 좋은 아이디어입니다. 그러나, 나는 다음과 같은 해결책을 종료 한 때문에 자신을 편안 매우 넓은 범위로이 일을 생각하지 않습니다 :

    CREATE TABLE DatesNumbers (
        i MEDIUMINT NOT NULL,
        PRIMARY KEY (i)
    )
    COMMENT='Used by Dates view'
    ;
    
    INSERT INTO DatesNumbers
    SELECT 
        a.i + (10 * b.i) + (100 * c.i) + (1000 * d.i) + (10000 * e.i) - 59999 AS i
    FROM 
      (SELECT 0 AS i 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) AS a,
      (SELECT 0 AS i 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) AS b,
      (SELECT 0 AS i 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) AS c,
      (SELECT 0 AS i 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) AS d,
      (SELECT 0 AS i 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) AS e
    ;
    
    SELECT
          i,
          CURRENT_DATE() + INTERVAL i DAY AS Date
    FROM
        DatesNumbers
    

    이게 다예요.

  19. ==============================

    19.좋아 ..이 시도 : http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/ http://dev.mysql.com/doc/refman/5.0/en/loop-statement.html http://www.roseindia.net/sql/mysql-example/mysql-loop.shtml

    좋아 ..이 시도 : http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/ http://dev.mysql.com/doc/refman/5.0/en/loop-statement.html http://www.roseindia.net/sql/mysql-example/mysql-loop.shtml

    말에, 임시 테이블을 생성 한 다음 임시 테이블에서 선택 *을 할 것을 사용합니다. 또는 한 번에 결과 하나의 출력. 당신은 당신이 SELECT 문을 수행 할 수 없습니다하고 싶은 말을하지만, MySQL의 물건의 특정와 함께 행할 수 있습니다 무엇. 그럼 다시, 어쩌면 당신이 커서가 필요합니다 http://dev.mysql.com/doc/refman/5.0/en/cursors.html

  20. ==============================

    20.Oracle의 경우, 내 솔루션입니다 :

    Oracle의 경우, 내 솔루션입니다 :

    select trunc(sysdate-dayincrement, 'DD') 
      from dual, (select level as dayincrement 
                    from dual connect by level <= 30)
    

    SYSDATE가 특정 날짜 및 레벨 번호를 변경할 수 있습니다 더 많은 날짜를 제공하기 위해 변경 될 수 있습니다.

  21. ==============================

    21.두 날짜 사이의 날짜의 목록을 원하는 경우 :

    두 날짜 사이의 날짜의 목록을 원하는 경우 :

    create table #dates ([date] smalldatetime)
    while @since < @to
    begin
         insert into #dates(dateadd(day,1,@since))
         set @since = dateadd(day,1,@since)
    end
    select [date] from #dates
    

    여기 * 바이올린 : http://sqlfiddle.com/#!6/9eecb/3469

  22. ==============================

    22.

    set language  'SPANISH'
    DECLARE @table table(fechaDesde datetime , fechaHasta datetime ) 
    INSERT @table VALUES('20151231' , '20161231');
    WITH x AS 
        (
            SELECT   DATEADD( m , 1 ,fechaDesde ) as fecha  FROM @table
            UNION ALL
            SELECT  DATEADD( m , 1 ,fecha )
            FROM @table t INNER JOIN x ON  DATEADD( m , 1 ,x.fecha ) <= t.fechaHasta
        )
    SELECT LEFT( CONVERT( VARCHAR, fecha , 112 ) , 6 ) as Periodo_Id 
    ,DATEPART ( dd, DATEADD(dd,-(DAY(fecha)-1),fecha)) Num_Dia_Inicio
    ,DATEADD(dd,-(DAY(fecha)-1),fecha) Fecha_Inicio
    ,DATEPART ( mm , fecha ) Mes_Id
    ,DATEPART ( yy , fecha ) Anio
    ,DATEPART ( dd, DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha))) Num_Dia_Fin
    ,DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha)) ultimoDia
    ,datename(MONTH, fecha) mes
    ,'Q' + convert(varchar(10),  DATEPART(QUARTER, fecha)) Trimestre_Name
    FROM x 
    OPTION(MAXRECURSION 0)
    
  23. ==============================

    23.

    DELIMITER $$
    CREATE PROCEDURE GenerateRangeDates(IN dateStart DATE, IN dateEnd DATE)
    BEGIN
    
        CREATE TEMPORARY TABLE IF NOT EXISTS dates (day DATE);
    
        loopDate: LOOP
            INSERT INTO dates(day) VALUES (dateStart); 
            SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);
    
            IF dateStart <= dateEnd 
                THEN ITERATE loopDate;
                ELSE LEAVE loopDate;
            END IF;
        END LOOP loopDate;
    
        SELECT day FROM dates;
        DROP TEMPORARY TABLE IF EXISTS dates;
    
    END 
    $$
    
    -- Call procedure
    call GenerateRangeDates( 
            now() - INTERVAL 40 DAY,
            now()
        );
    
  24. ==============================

    24.RedFilters 최고 솔루션의 SQLite는 버전

    RedFilters 최고 솔루션의 SQLite는 버전

    select d.Date
    from (
        select 
        date(julianday('2010-01-20') + (a.a + (10 * b.a) + (100 * c.a))) as Date
        from (select 0 as a 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) as a
        cross join (select 0 as a 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) as b
        cross join (select 0 as a 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) as c
    ) d
    where 
    d.Date between '2010-01-20' and '2010-01-24' 
    order by d.Date
    
  25. ==============================

    25.평일 참가에 사용자 지정 휴일 테이블 향상 의 PowerPivot 날짜 테이블에 대한 마이크로 소프트 MSSQL 2012 https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23b6e90e

    평일 참가에 사용자 지정 휴일 테이블 향상 의 PowerPivot 날짜 테이블에 대한 마이크로 소프트 MSSQL 2012 https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23b6e90e

    with [dates] as (
        select convert(datetime, '2016-01-01') as [date] --start
        union all
        select dateadd(day, 1, [date])
        from [dates]
        where [date] < '2018-01-01' --end
    )
    select [date]
    , DATEPART (dw,[date]) as Wochentag
    , (select holidayname from holidaytable 
    where holidaytable.hdate = [date]) 
    as Feiertag
    from [dates]
    where [date] between '2016-01-01' and '2016-31-12'
    option (maxrecursion 0)
    
  26. ==============================

    26.MySQL은 8.0.1 mariadb 10.2.2 재귀 공통 테이블 표현식을 사용하는 또 하나 개의 솔루션 :

    MySQL은 8.0.1 mariadb 10.2.2 재귀 공통 테이블 표현식을 사용하는 또 하나 개의 솔루션 :

    with recursive dates as (
        select '2010-01-20' as date
        union all
        select date + interval 1 day from dates where date < '2010-01-24'
    )
    select * from dates;
    
  27. ==============================

    27.

    WITH
      Digits AS (SELECT 0 D UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9),
      Dates AS (SELECT adddate('1970-01-01',t4.d*10000 + t3.d*1000 + t2.d*100 + t1.d*10 +t0.d) AS date FROM Digits AS t0, Digits AS t1, Digits AS t2, Digits AS t3, Digits AS t4)
    SELECT * FROM Dates WHERE date BETWEEN '2017-01-01' AND '2017-12-31'
    
  28. ==============================

    28.일에서 타임 스탬프 다른 달력 테이블을 만들 또한 프로 시저를 만들 수 있습니다. 각 분기 테이블을 원하는 경우

    일에서 타임 스탬프 다른 달력 테이블을 만들 또한 프로 시저를 만들 수 있습니다. 각 분기 테이블을 원하는 경우

    EG

    2019-01-22 08:45:00
    2019-01-22 09:00:00
    2019-01-22 09:15:00
    2019-01-22 09:30:00
    2019-01-22 09:45:00
    2019-01-22 10:00:00
    

    당신이 사용할 수있는

    CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_calendar_table`()
    BEGIN
    
    select unix_timestamp('2014-01-01 00:00:00') into @startts;
    select unix_timestamp('2025-01-01 00:00:00') into @endts;
    
    if ( @startts < @endts ) then
    
        DROP TEMPORARY TABLE IF EXISTS calendar_table_tmp;
    
        CREATE TEMPORARY TABLE calendar_table_tmp (ts int, dt datetime); 
    
        WHILE ( @startts < @endts)
            DO 
            SET @startts = @startts + 900;
            INSERT calendar_table_tmp VALUES (@startts, from_unixtime(@startts));
        END WHILE;
    
    END if;
    
    END
    
    
    

    다음 조작을 통하여

    select ts, dt from calendar_table_tmp;
    
    

    당신은 또한 TS를 제공하는 것이

    '1548143100', '2019-01-22 08:45:00'
    '1548144000', '2019-01-22 09:00:00'
    '1548144900', '2019-01-22 09:15:00'
    '1548145800', '2019-01-22 09:30:00'
    '1548146700', '2019-01-22 09:45:00'
    '1548147600', '2019-01-22 10:00:00'
    

    여기에서 당신과 같은 다른 정보를 추가 할 시작할 수 있습니다

    select ts, dt, weekday(dt) as wd from calendar_table_tmp;
    
    

    또는 테이블 문을 생성하여 실제 테이블을 생성

  29. ==============================

    29.AWS의 MySQL에서 작동하는보다 일반적인 대답.

    AWS의 MySQL에서 작동하는보다 일반적인 대답.

    select datetable.Date
    from (
        select date_format(adddate(now(),-(a.a + (10 * b.a) + (100 * c.a))),'%Y-%m-%d') AS Date
        from (select 0 as a 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) as a
    
        cross join (select 0 as a 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) as b
    
        cross join (select 0 as a 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) as c
    ) datetable
    where datetable.Date between now() - INTERVAL 14 Day and Now()
    order by datetable.Date DESC
    
  30. from https://stackoverflow.com/questions/2157282/generate-days-from-date-range by cc-by-sa and MIT license