복붙노트

[SQL] PostgreSQL의 쿼리에 대한 데이터가없는 일 및 디스플레이 일에 의해 계산 / 그룹

SQL

PostgreSQL의 쿼리에 대한 데이터가없는 일 및 디스플레이 일에 의해 계산 / 그룹

나는 반환하는 PostgreSQL의 쿼리를 작성해야

그것은 어떤 물체가 그 날 발견되지 않은 경우에도 매일이 결과에 표시하는 것이 중요합니다. (이것은 이전에 논의 된하지만 내 특정 사건에서 일하는 것을 얻을 수 없었다.)

첫째, 내가 가입 할 수있는 일의 범위를 생성하는 SQL 쿼리를 발견 :

SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
AS date 
FROM generate_series(0, 365, 1) 
AS offs

결과 :

    date    
------------
 2013-03-28
 2013-03-27
 2013-03-26
 2013-03-25
 ...
 2012-03-28
(366 rows)

지금은 '생성'열이 'sharer_emailshare'라는 이름의 테이블에 그 가입을 시도하고있다 :

Table 'public.sharer_emailshare'
column    |   type  
-------------------
id        | integer
created   | timestamp with time zone
message   | text
to        | character varying(75)

여기에 지금까지 가지고 쿼리 BY 최고의 그룹이다 :

SELECT d.date, count(se.id) FROM (
    select to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
    AS date 
    FROM generate_series(0, 365, 1) 
    AS offs
    ) d 
JOIN sharer_emailshare se 
ON (d.date=to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))  
GROUP BY d.date;

결과 :

    date    | count 
------------+-------
 2013-03-27 |    11
 2013-03-24 |     2
 2013-02-14 |     2
(3 rows)

원하는 결과 :

    date    | count 
------------+-------
 2013-03-28 |     0
 2013-03-27 |    11
 2013-03-26 |     0
 2013-03-25 |     0
 2013-03-24 |     2
 2013-03-23 |     0
 ...
 2012-03-28 |     0
(366 rows)

만약 내가 제대로 이해하고 내가 (INNER 암시) 일반 가입을 사용하고, 그리고 포스트 그레스 문서에 설명 된대로이 예상되는 동작입니다 때문입니다.

I에 유래 솔루션을 통해 수십 살펴본 작업 쿼리 모든 사람은 MySQL은 / ​​오라클 / MSSQL 특정 보인다 내가 PostgreSQL을로 변환하는 힘든 시간을 보내고 있습니다.

이 질문을 남자는 포스트 그레스와 함께, 그의 대답을 찾았지만, 얼마 전에 만료 페이스트 빈 링크를 넣어.

나는 널 (null), 유착 등등, 기본값을 제공 할 경우, RIGHT, RIGHT OUTER JOIN은, CROSS JOIN은, 다른 값에서 하위에 CASE 문을 사용하여 조인 LEFT OUTER로 전환하려면 시도했다, 그러나 나는 할 수 없었다 내가 원하는 걸 얻는 방법을 사용합니다.

모든 지원에 감사드립니다! 그리고 나는 곧 거대한 PostgreSQL의 책을 읽고 주위에 얻을 것이다 약속)

해결법

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

    1.당신은 왼쪽 외부가 아닌 내부의 조인이 필요합니다

    당신은 왼쪽 외부가 아닌 내부의 조인이 필요합니다

    SELECT d.date, count(se.id)
    FROM (SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD') AS date 
          FROM generate_series(0, 365, 1) AS offs
         ) d LEFT OUTER JOIN
         sharer_emailshare se 
         ON d.date = to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))  
    GROUP BY d.date;
    
  2. ==============================

    2.고든 리노 프의 도움이 대답을 확장하는 것은, 나는 다음과 같은 개선의 몇 가지를 제안합니다 :

    고든 리노 프의 도움이 대답을 확장하는 것은, 나는 다음과 같은 개선의 몇 가지를 제안합니다 :

    여기 내 쿼리는 다음과 같습니다

    WITH dates_table AS (
        SELECT created::date AS date_column FROM sharer_emailshare WHERE showroom_id=5
    )
    SELECT series_table.date, COUNT(dates_table.date_column), SUM(COUNT(dates_table.date_column)) OVER (ORDER BY series_table.date) FROM (
        SELECT (last_date - b.offs) AS date
            FROM (
                SELECT GENERATE_SERIES(0, last_date - first_date, 1) AS offs, last_date from (
                     SELECT MAX(date_column) AS last_date, (MAX(date_column) - '1 year'::interval)::date AS first_date FROM dates_table
                ) AS a
            ) AS b
    ) AS series_table
    LEFT OUTER JOIN dates_table
        ON (series_table.date = dates_table.date_column)
    GROUP BY series_table.date
    ORDER BY series_table.date
    

    나는 쿼리를 테스트하고,이 같은 결과, 플러스 누적 총 열을 생산하고 있습니다.

  3. ==============================

    3.고든 리노 프의 답변에 따라 나는 또 다른 문제는 내가 원래의 질문에 언급하지 않았다 WHERE 절을 한 것으로 깨달았다.

    고든 리노 프의 답변에 따라 나는 또 다른 문제는 내가 원래의 질문에 언급하지 않았다 WHERE 절을 한 것으로 깨달았다.

    대신 알몸 WHERE, 나는 하위 쿼리를했다 :

    SELECT d.date, count(se.id) FROM (
        select to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
        AS date 
        FROM generate_series(0, 365, 1) 
        AS offs
        ) d 
    LEFT OUTER JOIN (
        SELECT * FROM sharer_emailshare 
        WHERE showroom_id=5
    ) se
    ON (d.date=to_char(date_trunc('day', se.created), 'YYYY-MM-DD')) 
    GROUP BY d.date;
    
  4. ==============================

    4.나는 약간의 설명을 포함하는 답을 제공하기 위해 노력하겠습니다. 나는 작은 빌딩 블록으로 시작하고 최대 일 것입니다.

    나는 약간의 설명을 포함하는 답을 제공하기 위해 노력하겠습니다. 나는 작은 빌딩 블록으로 시작하고 최대 일 것입니다.

    이 같은 쿼리를 실행하는 경우 :

    SELECT series.number FROM generate_series(0, 9) AS series(number)
    

    이 같은 출력을 얻을 :

     number 
    --------
          0
          1
          2
          3
          4
          5
          6
          7
          8
          9
    (10 rows)
    

    이는 같은 기간으로 설정할 수 있습니다 :

    SELECT CURRENT_DATE + sequential_dates.date AS date
      FROM generate_series(0, 9) AS sequential_dates(date)
    

    어떤이 같은 출력을 제공합니다 :

        date    
    ------------
     2019-09-29
     2019-09-30
     2019-10-01
     2019-10-02
     2019-10-03
     2019-10-04
     2019-10-05
     2019-10-06
     2019-10-07
     2019-10-08
    (10 rows)
    

    그럼 당신은 당신이 궁극적으로 관심이 어떤 테이블에 대한 하위 쿼리로 원래 쿼리에 합류, (예를 들어)이 같은 쿼리를 수행 할 수 있습니다

       SELECT sequential_dates.date,
              COUNT(calendar_items.*) AS calendar_item_count
         FROM (SELECT CURRENT_DATE + sequential_dates.date AS date
                 FROM generate_series(0, 9) AS sequential_dates(date)) sequential_dates
    LEFT JOIN calendar_items ON calendar_items.starts_at::date = sequential_dates.date
     GROUP BY sequential_dates.date
    

    어떤이 같은 출력을 제공합니다 :

        date    | calendar_item_count 
    ------------+---------------------
     2019-09-29 |                   1
     2019-09-30 |                   8
     2019-10-01 |                  15
     2019-10-02 |                  11
     2019-10-03 |                   1
     2019-10-04 |                  12
     2019-10-05 |                   0
     2019-10-06 |                   0
     2019-10-07 |                  27
     2019-10-08 |                  24
    
  5. from https://stackoverflow.com/questions/15691127/postgresql-query-to-count-group-by-day-and-display-days-with-no-data by cc-by-sa and MIT license