[SQL] 오라클 : 어떻게 이상의 범위 "에 의해 그룹"에?
SQL오라클 : 어떻게 이상의 범위 "에 의해 그룹"에?
이 같은 테이블이있는 경우 :
pkey age
---- ---
1 8
2 5
3 12
4 12
5 22
나는 "에 의해 그룹은"각 시대의 수를 얻을 수 있습니다.
select age,count(*) n from tbl group by age;
age n
--- -
5 1
8 1
12 2
22 1
나는 연령대로 그룹에 어떤 쿼리를 사용할 수 있습니까?
age n
----- -
1-10 2
11-20 2
20+ 1
나는 10gR2의에,하지만 난 잘으로 접근 어떤 11g 별에 관심이있을 것입니다.
해결법
-
==============================
1.
SELECT CASE WHEN age <= 10 THEN '1-10' WHEN age <= 20 THEN '11-20' ELSE '21+' END AS age, COUNT(*) AS n FROM age GROUP BY CASE WHEN age <= 10 THEN '1-10' WHEN age <= 20 THEN '11-20' ELSE '21+' END
-
==============================
2.시험:
시험:
select to_char(floor(age/10) * 10) || '-' || to_char(ceil(age/10) * 10 - 1)) as age, count(*) as n from tbl group by floor(age/10);
-
==============================
3.당신이 찾고있는 것은 기본적으로 히스토그램 데이터입니다.
당신이 찾고있는 것은 기본적으로 히스토그램 데이터입니다.
당신은 y 축에 나이 (연령 범위) x 축에 카운트 N (또는 주파수)를 가질 것이다.
이미 설명한 것처럼 간단한 형태로, 하나는 단순히 각각 별개의 세 값의 수를 셀 수 :
SELECT age, count(*) FROM tbl GROUP BY age
그러나, X 축에 대해 너무 많은 다른 값이 존재하는 경우, 하나의 그룹 (또는 클러스터 또는 버킷)를 생성 할 수있다. 10의 일정한 범위에 의해 귀하의 경우에, 당신은 그룹.
우리는 각각의 범위에 대한 WHEN ... THEN 라인을 작성 피할 수 있습니다 - 그것은 나이 아니었다면 수백있을 수 있습니다. 대신, @MatthewFlaschen에 의한 접근 방식은 @NitinMidha 언급 이유로 바람직하다.
이제 SQL을 만들어 보자 ...
첫째, 우리는 그렇게 같은 10의 범위-그룹으로 세를 분할해야합니다
이것은 10 세 열을 분할하고, 그 결과의 FLOOR를 계산함으로써 달성 될 수있다 :
FLOOR(age/10)
"FLOOR는 N보다 작거나 같은 정수 가장 큰 반환" http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions067.htm#SQLRF00643
그 후 우리는 원래의 SQL을 가지고 그 표현과 나이를 대체 :
SELECT FLOOR(age/10), count(*) FROM tbl GROUP BY FLOOR(age/10)
이것은 OK이지만, 우리는 아직 범위를 볼 수 없습니다. 그 대신 우리는 0, 1, 2 ... n은 계산 된 바닥 값을 참조.
실제이 하한 얻으려면, 우리는 다시 10을 곱해야하는 우리 얻을 0, 10, 20 ... N :
FLOOR(age/10) * 10
우리는 또한 상하 + (10)를 결합되어 각 범위의 하한 필요 - 1
FLOOR(age/10) * 10 + 10 - 1
마지막으로, 우리는이 같은 문자열로 둘을 연결 :
TO_CHAR(FLOOR(age/10) * 10) || '-' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1)
이 만듭니다 '0-9', '10 -19 ', '20 -29'등
이 같은 이제 우리의 SQL의 외모 :
SELECT TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1), COUNT(*) FROM tbl GROUP BY FLOOR(age/10)
마지막으로, 주문 및 좋은 열 별칭을 적용
SELECT TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1) AS range, COUNT(*) AS frequency FROM tbl GROUP BY FLOOR(age/10) ORDER BY FLOOR(age/10)
그러나 더 복잡한 시나리오에서,이 범위의 크기는 10의 일정한 덩어리로 분류하지만, 동적 클러스터링을 필요로하지 않을 수 있습니다. 오라클이 포함 된 고급 히스토그램 기능을 가지고, http://docs.oracle.com/cd/E16655_01/server.121/e15858/tgsql_histo.htm#TGSQL366 참조
그의 접근에 대한 @MatthewFlaschen에 크레딧; 난 단지 세부 사항을 설명했다.
-
==============================
4.여기서 서브 쿼리에 "범위"테이블을 생성하고 기본 테이블의 데이터를 분할하기 위해 사용하는 용액이다 :
여기서 서브 쿼리에 "범위"테이블을 생성하고 기본 테이블의 데이터를 분할하기 위해 사용하는 용액이다 :
SELECT DISTINCT descr , COUNT(*) OVER (PARTITION BY descr) n FROM age_table INNER JOIN ( select '1-10' descr, 1 rng_start, 10 rng_stop from dual union ( select '11-20', 11, 20 from dual ) union ( select '20+', 21, null from dual )) ON age BETWEEN nvl(rng_start, age) AND nvl(rng_stop, age) ORDER BY descr;
-
==============================
5.한 시간에 등장 얼마나 많은 트랜잭션 데이터를 그룹화했다. 나는 타임 스탬프에서 시간을 추출하여 이런 짓을 :
한 시간에 등장 얼마나 많은 트랜잭션 데이터를 그룹화했다. 나는 타임 스탬프에서 시간을 추출하여 이런 짓을 :
select extract(hour from transaction_time) as hour ,count(*) from table where transaction_date='01-jan-2000' group by extract(hour from transaction_time) order by extract(hour from transaction_time) asc ;
출력주기 :
HOUR COUNT(*) ---- -------- 1 9199 2 9167 3 9997 4 7218
당신이 볼 수 있듯이,이 시간 당 레코드 수를 그룹화하는 좋은 쉬운 방법을 제공합니다.
-
==============================
6.대신하여 테이블과 그룹에 AGE_RANGE 테이블과 age_range_id 필드를 추가합니다.
대신하여 테이블과 그룹에 AGE_RANGE 테이블과 age_range_id 필드를 추가합니다.
// DDL을 실례 그러나 당신은 생각을해야한다
create table age_range( age_range_id tinyint unsigned not null primary key, name varchar(255) not null); insert into age_range values (1, '18-24'),(2, '25-34'),(3, '35-44'),(4, '45-54'),(5, '55-64');
// 다시 DML 실례 그러나 당신은 생각을해야한다
select count(*) as counter, p.age_range_id, ar.name from person p inner join age_range ar on p.age_range_id = ar.age_range_id group by p.age_range_id, ar.name order by counter desc;
AGE_RANGE 테이블 등의 from_age to_age의 열을 추가 - - 만약 당신이 좋아하면 당신은이 아이디어를 구체화 할 수 있습니다하지만 난 당신을 떠날 것이다.
도움이 되었기를 바랍니다 :)
-
==============================
7.오라클 9i에 +를 사용하는 경우, 당신은 NTILE 분석 기능을 사용할 수 있습니다 :
오라클 9i에 +를 사용하는 경우, 당신은 NTILE 분석 기능을 사용할 수 있습니다 :
WITH tiles AS ( SELECT t.age, NTILE(3) OVER (ORDER BY t.age) AS tile FROM TABLE t) SELECT MIN(t.age) AS min_age, MAX(t.age) AS max_age, COUNT(t.tile) As n FROM tiles t GROUP BY t.tile
NTILE에주의해야 할 점은 당신이 단지 파티션이 아닌 브레이크 포인트 자체의 수를 지정할 수 있다는 것입니다. 그래서 당신은 적절한 숫자를 지정해야합니다. IE는 100 행, NTILE (4)는 네 개의 버킷 / 파티션 각각 25 행에 충당한다. 당신은 둥지를 분석하지 기능, 그래서 당신은 원하는 입도를 얻기 위해 서브 쿼리 / 하위 쿼리 인수 분해를 사용하여 레이어해야 할 것입니다 수 있습니다. 그렇지 않으면, 사용 :
SELECT CASE t.age WHEN BETWEEN 1 AND 10 THEN '1-10' WHEN BETWEEN 11 AND 20 THEN '11-20' ELSE '21+' END AS age, COUNT(*) AS n FROM TABLE t GROUP BY CASE t.age WHEN BETWEEN 1 AND 10 THEN '1-10' WHEN BETWEEN 11 AND 20 THEN '11-20' ELSE '21+' END
-
==============================
8.나는 하루 샘플의 수를 얻을 수 있었다. @Clarkey I에 의해 영감은 ISO-8601 날짜 형식으로 타임 스탬프의 샘플의 날짜를 추출하는 TO_CHAR를 사용하여 GROUP BY의 것을 사용하고 ORDER BY 절. (또한 영감, 나 또한 다른 사람에게 유용 경우 여기를 게시 할 수 있습니다.)
나는 하루 샘플의 수를 얻을 수 있었다. @Clarkey I에 의해 영감은 ISO-8601 날짜 형식으로 타임 스탬프의 샘플의 날짜를 추출하는 TO_CHAR를 사용하여 GROUP BY의 것을 사용하고 ORDER BY 절. (또한 영감, 나 또한 다른 사람에게 유용 경우 여기를 게시 할 수 있습니다.)
SELECT TO_CHAR(X.TS_TIMESTAMP, 'YYYY-MM-DD') AS TS_DAY, COUNT(*) FROM TABLE X GROUP BY TO_CHAR(X.TS_TIMESTAMP, 'YYYY-MM-DD') ORDER BY TO_CHAR(X.TS_TIMESTAMP, 'YYYY-MM-DD') ASC /
-
==============================
9.당신은 솔루션 아래 시도 할 수 있습니다 :
당신은 솔루션 아래 시도 할 수 있습니다 :
SELECT count (1), '1-10' where age between 1 and 10 union all SELECT count (1), '11-20' where age between 11 and 20 union all select count (1), '21+' where age >20 from age
-
==============================
10.나의 접근 방식 :
나의 접근 방식 :
select range, count(1) from ( select case when age < 5 then '0-4' when age < 10 then '5-9' when age < 15 then '10-14' when age < 20 then '15-20' when age < 30 then '21-30' when age < 40 then '31-40' when age < 50 then '41-50' else '51+' end as range from (select round(extract(day from feedback_update_time - feedback_time), 1) as age from txn_history ) ) group by range
from https://stackoverflow.com/questions/2483140/oracle-how-to-group-by-over-a-range by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 쿼리를 실행하기 위해 R 스크립트 내로 .SQL 파일의 내용을 읽어? (0) | 2020.07.23 |
---|---|
[SQL] 단지 SQL과 파일에 MySQL 데이터베이스에서 물방울 내보내기 (0) | 2020.07.23 |
[SQL] 다른 테이블에 외래 키를 포함하는 테이블에서 행을 삭제하는 방법 (0) | 2020.07.23 |
[SQL] 두 개의 SQL 쿼리를 가입 (0) | 2020.07.23 |
[SQL] 항목의 모든 조상을 얻는다 SQL 재귀 쿼리 (0) | 2020.07.23 |