[SQL] 어떻게 하루에 1 개 이상의 레코드를 선택하려면?
SQL어떻게 하루에 1 개 이상의 레코드를 선택하려면?
이것은 PostgreSQL의 문제입니다.
PostgreSQL 8.3.3 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-9).
테이블 외모가 좋아 :
date_time other_column
2012-11-01 00:00:00 ...
2012-11-02 01:00:00 ...
2012-11-02 02:00:00 ...
2012-11-02 03:00:00 ...
2012-11-02 04:00:00 ...
2012-11-03 05:00:00 ...
2012-11-03 06:00:00 ...
2012-11-05 00:00:00 ...
2012-11-07 00:00:00 ...
2012-11-07 00:00:00 ...
...
나는 특정 날짜 범위에서 하루에 최대 3 개 레코드를 선택합니다.
예를 들어, 나는 2012년 11월 2일에서 2012년 11월 5일 대부분의 3 개 기록을 선택합니다. 예상되는 결과는 다음과 같습니다
date_time other_column
2012-11-02 01:00:00 ...
2012-11-02 02:00:00 ...
2012-11-02 03:00:00 ...
2012-11-03 05:00:00 ...
2012-11-03 06:00:00 ...
2012-11-05 00:00:00 ...
나는이에 몇 시간을 보냈습니다 아직도 그것을 알아낼 수 없습니다. 제발 도와주세요. :(
최신 정보: 단 하루에 하나 개의 레코드를 선택할 수 있습니다 시도 현재 SQL I :
SELECT DISTINCT ON (TO_DATE(SUBSTRING((date_time || '') FROM 1 FOR 10), 'YYYY-MM-DD')) *
FROM myTable
WHERE date_time >= '20121101 00:00:00'
AND date_time <= '20121130 23:59:59'
해결법
-
==============================
1.
SELECT date_time, other_column FROM ( SELECT *, row_number() OVER (PARTITION BY date_time::date) AS rn FROM tbl WHERE date_time >= '2012-11-01 0:0' AND date_time < '2012-12-01 0:0' ) x WHERE rn < 4;
최선의 해결책 : 바람직 현재 버전 9.2, 최신 버전으로 업그레이드합니다.
기타 솔루션 :
단지 몇 일 동안 당신은 UNION ALL을 사용 수 :
SELECT date_time, other_column FROM tbl t1 WHERE date_time >= '2012-11-01 0:0' AND date_time < '2012-11-02 0:0' LIMIT 3 ) UNION ALL ( SELECT date_time, other_column FROM tbl t1 WHERE date_time >= '2012-11-02 0:0' AND date_time < '2012-11-03 0:0' LIMIT 3 ) ...
괄호는 여기에 선택되지 않습니다.
나는 같은 (자세한에 대한 링크를 포함하여) 여기에 게시 - 일 이상 generate_series와 해결 방법 ()가 있습니다.
우리가 윈도우 기능을 가지기 전에 나는 옛날에 plpgsql 기능 다시 그것을 해결 한 수 있습니다
CREATE OR REPLACE FUNCTION x.f_foo (date, date, integer , OUT date_time timestamp, OUT other_column text) RETURNS SETOF record AS $BODY$ DECLARE _last_day date; -- remember last day _ct integer := 1; -- count BEGIN FOR date_time, other_column IN SELECT t.date_time, t.other_column FROM tbl t WHERE t.date_time >= $1::timestamp AND t.date_time < ($2 + 1)::timestamp ORDER BY t.date_time::date LOOP IF date_time::date = _last_day THEN _ct := _ct + 1; ELSE _ct := 1; END IF; IF _ct <= $3 THEN RETURN NEXT; END IF; _last_day := date_time::date; END LOOP; END; $BODY$ LANGUAGE plpgsql STABLE STRICT; COMMENT ON FUNCTION f_foo(date3, date, integer) IS 'Return n rows per day $1 .. date_from (incl.) $2 .. date_to (incl.) $3 .. maximim rows per day';
요구:
SELECT * FROM f_foo('2012-11-01', '2012-11-05', 3);
-
==============================
2.다음은 모든 사용 date_trunc ( '일', DATE_TIME)하거나 날짜에 타임 스탬프를 절단하는 최신 캐스트에 응답합니다. 날짜 형식 문자열과 남이 할 필요가 없습니다. 설명서에 날짜 / 시간 함수를 참조하십시오.
다음은 모든 사용 date_trunc ( '일', DATE_TIME)하거나 날짜에 타임 스탬프를 절단하는 최신 캐스트에 응답합니다. 날짜 형식 문자열과 남이 할 필요가 없습니다. 설명서에 날짜 / 시간 함수를 참조하십시오.
이 SQLFiddle 방송 세 가지 응답 : http://sqlfiddle.com/#!12/0fd51/14 (DATE_TIME 그것에 중복을 가질 수 있다면, 반드시 동일한 결과하지만)는 입력 데이터에 대해 동일한 결과를 모두.
문제를 해결하려면에 필터에 대한 IN-목록을 생성 한계와 상관 하위 쿼리를 사용할 수 있습니다 :
SELECT a.date_time, a.other_column FROM table1 a WHERE a.date_time IN ( SELECT b.date_time FROM table1 b WHERE b.date_time IS NOT NULL AND a.date_time::date = b.date_time::date ORDER BY b.date_time LIMIT 3 ) AND a.date_time::date BETWEEN '2012-11-02' AND '2012-11-05';
이것은 대부분의 휴대용 접근해야한다 - 그것은 MySQL을하지 작업 (5.5 같은 적어도) MySQL은 IN 절에서 사용되는 하위 쿼리에 LIMIT를 지원하지 않기 때문에 비록. 그래도, sqlite3를과 PostgreSQL에서 작동, 및 대부분의 다른 데시벨에서 작동합니다.
또 다른 옵션은, 당신이 원하는 날짜 범위를 선택 창 기능을 사용하여 행 번호 범위 내에서 행을 주석하는 것입니다, 다음 여분의 행을 제외 출력을 필터링 :
SELECT date_time, other_column FROM ( SELECT date_time, other_column, rank() OVER (PARTITION BY date_trunc('day',date_time) ORDER BY date_time) AS n FROM Table1 WHERE date_trunc('day',date_time) BETWEEN '2012-11-02' AND '2012-11-05' ORDER BY date_time ) numbered_rows WHERE n < 4;
DATE_TIME이 고유하지 않으면 관계가 가능성, 즉 인 경우에, 결정 결과를 얻을, 또는 넥타이를 깨고 ROW_NUMBER에 의해 순서에 추가 조항을 추가하는 대신 ROW_NUMBER 중 하나 계급 또는 DENSE_RANK 창 기능을 사용하는 것이 좋습니다.
당신이 순위를 사용하는 경우, 그것은 그들 모두를 적합 할 수없는 경우 행을 전혀 포함하지 것이다; 당신이 DENSE_RANK 사용하는 경우 그것은 그렇게 할 수있는 3 행 당 하루에 제한을 통해 이동하는 경우에도 모두 포함됩니다.
다른 처리의 모든 종류의 윈도우 사양을 사용하여,이 방법도 가능합니다.
여기에 완전히 PostgreSQL의 특정 있지만 재미 배열 집계 및 슬라이스를 사용하는 다른 제제는 아직입니다.
SELECT b.date_time, b.other_column FROM ( SELECT array_agg(a.date_time ORDER BY a.date_time) FROM table1 a WHERE a.date_time::date BETWEEN '2012-11-02' AND '2012-11-05' GROUP BY a.date_time::date ) x(arr) INNER JOIN table1 b ON (b.date_time = ANY (arr[1:3]));
-
==============================
3.나는 서브 - 선택 사용할 것이며, 왼쪽 외부 조인. 이 트릭을 수행해야합니다
나는 서브 - 선택 사용할 것이며, 왼쪽 외부 조인. 이 트릭을 수행해야합니다
select distinct(date_format(a.date_time,"%Y-%m-%d")) date_time, b.* from table a left outer join ( select date_format(date_time,"%Y-%m-%d") dt, * from table limit 3 ) b on date_format(a.date_time,"%Y-%m-%d") = b.dt;
from https://stackoverflow.com/questions/13410315/how-to-select-more-than-1-record-per-day by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] TSQL : 어떻게 주어진 날짜 범위 사이의 각 달의 마지막 날짜를 검색 (0) | 2020.07.15 |
---|---|
[SQL] 전체는 MS 액세스에 가입 (0) | 2020.07.15 |
[SQL] 5 세트로 그룹 행 (0) | 2020.07.15 |
[SQL] 오라클 SQL 구문 : 인용 식별자 (0) | 2020.07.15 |
[SQL] 오늘 날짜를 기준으로 이전 월요일 및 이전 일요일의 날짜 (0) | 2020.07.15 |