Посчитать колличество записей по группам

the_moon
Дата: 07.03.2011 12:07:20
Привет,

есть табличка с нумерическим полем, надо посчитать колличество записей по группам. Типа того:

автор
select 1, count(1), min(id), max(id) from mytable where id >= 0 and id < 1000
union
select 1, count(1), min(id), max(id) from mytable where id >= 1000 and id < 2000
union
select 1, count(1), min(id), max(id) from mytable where id >= 2000 and id < 3000


Это нормальное решение или можно как то круче/эффективнее написать? Таких груп всего 10.

Спасибо
GL
Дата: 07.03.2011 12:22:04
the_moon,

group by trunc(id,-3)
the moon
Дата: 07.03.2011 12:51:43
Спасибо, разобрался.
автор
select 1, count(1), min(id), max(id) from mytable where id >= 0 and id < 1000 group by trunc(id,-3)
union
select 1, count(1), min(id), max(id) from mytable where id >= 1000 and id < 2000 group by trunc(id,-3)
union
select 1, count(1), min(id), max(id) from mytable where id >= 2000 and id < 3000 group by trunc(id,-3)
the_moon
Дата: 07.03.2011 13:06:25
GL
the_moon,

group by trunc(id,-3)


О! Кул! Спасибо. Немного тормознутее, но писать меньше :)
the moon
Дата: 07.03.2011 13:32:42
the_moon
Немного тормознутее

Па-любому, десять сканов + сортировка/хеширование (второе слагаемое явно говорит об "умелости" топикстартера) работает быстрее одного скана и групбая.
SY
Дата: 07.03.2011 13:46:13
the_moon
Немного тормознутее




What GL had in mind:

select  1,
        count(id),
        min(id),
        max(id)
  from  mytable
  where id >= 0
    and id <  3000
    group by trunc(id,-3)
/
the_moon
Дата: 07.03.2011 15:17:13
Не пойму о чем вы, но действительно тормознутее на 10.2. Хотя план исполнения и попроще и оракл кажет, что второй должен быть быстрее, но на второй запрос оракл отдает данные на секнуду позже, чем на мою атаку в лоб. Мой вариант 0.33s, второй вариант 1.20s.


---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 50 | | 2692 (100)| 00:00:33 |
| 1 | SORT UNIQUE | | 10 | 50 | 9M| 2692 (100)| 00:00:33 |
| 2 | UNION-ALL | | | | | | |
| 3 | SORT AGGREGATE | | 1 | 5 | | 14 (8)| 00:00:01 |
|* 4 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 3955 | 19775 | | 13 (0)| 00:00:01 |
| 5 | SORT AGGREGATE | | 1 | 5 | | 503 (2)| 00:00:07 |
|* 6 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 86372 | 421K| | 233 (1)| 00:00:03 |
| 7 | SORT AGGREGATE | | 1 | 5 | | 516 (2)| 00:00:07 |
|* 8 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 88585 | 432K| | 239 (1)| 00:00:03 |
| 9 | SORT AGGREGATE | | 1 | 5 | | 9 (12)| 00:00:01 |
|* 10 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 2187 | 10935 | | 8 (0)| 00:00:01 |
| 11 | SORT AGGREGATE | | 1 | 5 | | 6 (17)| 00:00:01 |
|* 12 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 858 | 4290 | | 5 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 5 | | 55 (4)| 00:00:01 |
|* 14 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 18978 | 94890 | | 53 (0)| 00:00:01 |
| 15 | SORT AGGREGATE | | 1 | 5 | | 146 (4)| 00:00:02 |
|* 16 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 52091 | 254K| | 142 (1)| 00:00:02 |
| 17 | SORT AGGREGATE | | 1 | 5 | | 516 (2)| 00:00:07 |
|* 18 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 88731 | 433K| | 239 (1)| 00:00:03 |
| 19 | SORT AGGREGATE | | 1 | 5 | | 515 (2)| 00:00:07 |
|* 20 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 88515 | 432K| | 238 (1)| 00:00:03 |
| 21 | SORT AGGREGATE | | 1 | 5 | | 412 (2)| 00:00:05 |
|* 22 | INDEX RANGE SCAN| PK_SEB_VU_ROH | 70878 | 346K| | 192 (1)| 00:00:03 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - access("VU_NR">=0 AND "VU_NR"<100000)
6 - access("VU_NR">=100000 AND "VU_NR"<200000)
8 - access("VU_NR">=200000 AND "VU_NR"<300000)
10 - access("VU_NR">=300000 AND "VU_NR"<400000)
12 - access("VU_NR">=400000 AND "VU_NR"<500000)
14 - access("VU_NR">=500000 AND "VU_NR"<600000)
16 - access("VU_NR">=600000 AND "VU_NR"<700000)
18 - access("VU_NR">=700000 AND "VU_NR"<800000)
20 - access("VU_NR">=800000 AND "VU_NR"<900000)
22 - access("VU_NR">=900000 AND "VU_NR"<1000000)

И второй вариант

Plan hash value: 3404201777                                                                     

-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 503K| 2456K| | 1856 (3)| 00:00:23 |
| 1 | HASH GROUP BY | | 503K| 2456K| 11M| 1856 (3)| 00:00:23 |
| 2 | INDEX FAST FULL SCAN| PK_SEB_VU_ROH | 503K| 2456K| | 299 (2)| 00:00:04 |
-----------------------------------------------------------------------------------------------
-2-
Дата: 07.03.2011 17:13:37
Постояльцы заинтригованы.
the_moon
Дата: 07.03.2011 17:41:30
the moon
Спасибо, разобрался.
автор
select 1, count(1), min(id), max(id) from mytable where id >= 0 and id < 1000 group by trunc(id,-3)
union
select 1, count(1), min(id), max(id) from mytable where id >= 1000 and id < 2000 group by trunc(id,-3)
union
select 1, count(1), min(id), max(id) from mytable where id >= 2000 and id < 3000 group by trunc(id,-3)


Кстати это не я писал, только сейчас заметил, что кто то от моего имени запостил.
dbms_photoshop
Дата: 07.03.2011 19:05:14
the_moon
Не пойму о чем вы, но действительно тормознутее на 10.2.
Приведи планы с помощью следующего скрипта:
alter session set statistics_level = 'ALL';
select * from dual; -- тут твой запрос
select * from table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST'));
Вместо alter session set statistics_level = 'ALL'; можешь повставлять в запросы хинт gather_plan_statistics.
А то ты с одной стороны показываешь ожидаемое, а рассказываешь про фактическое.