SQL을 분리하면 범위가 있습니다
-
03-07-2019 - |
문제
숫자로 인덱싱 된 멤버 목록에서 간단한 쿼리를 사용하여 동일한 크기의 '버킷'으로 그룹화하고 싶습니다. 기본 쿼리는 다음과 같습니다.
select my_members.member_index from my_members where my_members.active=1;
1000 명의 멤버 인덱스 숫자를 다시 얻었습니다. 이제 최대 및 최소 회원 지수로 동일 크기의 그룹으로 분할하고 싶습니다. 같은 것 :
0에서 400 : 100 명의 활동적인 회원 401 ~ 577 : 100 ... 1584 년부터 1765 년까지 활성 회원 : 100
내가 생각해 낼 수있는 최선은 Rownum 한계가 증가한 Max (my_members.member_index)를 반복적으로 쿼리하는 것입니다.
for r in 1 .. 10 loop
select max(my_members.member_index)
into ranges(r)
from my_members
where my_members.active = 1
and rownum < top_row
order by my_members.member_index asc;
top_row := top_row + 100;
end loop;
해결책
Ntile은 SQL을 크게 단순화 할 수 있으므로 분석 기능을 읽을 가치가 있습니다.
원래 코드에 대한 작은 의견 - rownum 제한 수행 ~ 전에 주문은 불리한 결과를 낳을 수 있습니다
for r in 1 .. 10 loop
select max(my_members.member_index)
into ranges(r)
from my_members
where my_members.active = 1
and rownum < top_row
order by my_members.member_index asc;
top_row := top_row + 100;
엔드 루프;
다음을 시도하십시오.
create table example_nums (numval number)
begin
for i in 1..100 loop
insert into example_nums values (i);
end loop;
end;
SELECT numval FROM example_nums
WHERE rownum < 5
ORDER BY numval DESC;
결과를 얻으려면
SELECT numval FROM
(SELECT numval FROM example_nums
ORDER BY numval DESC)
WHERE rownum < 5
(참고 - 무대 뒤에서 Oracle은 이것을 '상위 4 개 항목'만 보유하는 효율적인 종류로 번역합니다).
다른 팁
Ntile 분석 기능을 사용하여 간단하고 훨씬 빠릅니다.
SELECT member_index, NTILE(10) OVER (ORDER BY member_index) FROM my_members;
Oracle 10G 문서 : "Ntile은 분석 기능입니다. 주문한 데이터 세트를 Expr로 표시된 여러 버킷으로 나누고 각 행에 적절한 버킷 번호를 할당합니다. 버킷은 1에서 Expr로 번호가 매겨집니다."
도와 주셔서 감사합니다. 모든 것을 하나의 진술로 일하는 데 시간이 걸렸습니다 (목표였던 특정 이유로).
select max(member_index), ranger
from (SELECT member_index,
CASE
WHEN rownum < sized THEN 1
WHEN rownum < sized*2 THEN 2
WHEN rownum < sized*3 THEN 3
WHEN rownum < sized*4 THEN 4
WHEN rownum < sized*5 THEN 5
WHEN rownum < sized*6 THEN 6
WHEN rownum < sized*7 THEN 7
WHEN rownum < sized*8 THEN 8
WHEN rownum < sized*9 THEN 9
ELSE 10
END ranger
from my_members,
(select count(*) / 10 sized
from my_members
where active = 1)
where active = 1
order by member_index)
group by ranger;
다음과 같은 내 결과를 줘 :
member_index ranger
2297683 1
2307055 2
2325667 3
2334819 4
2343982 5
2353325 6
2362247 7
6229146 8
8189767 9
26347329 10
SQL의 CASE 문을 살펴보고 원하는 범위를 기반으로 그룹 필드를 설정하십시오.