powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Можно ли такое сделать запросом?
21 сообщений из 21, страница 1 из 1
Можно ли такое сделать запросом?
    #32438869
x.diablo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исходные данные:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE TABLE TAB1 (
     "Code"   INTEGER,
     "Name"   VARCHAR( 100 )
);

INSERT INTO TAB1 ( "Code" ,  "Name" ) VALUES ( 1 , '1234567');
INSERT INTO TAB1 ( "Code" ,  "Name" ) VALUES ( 2 , '1234567');
INSERT INTO TAB1 ( "Code" ,  "Name" ) VALUES ( 3 , '321');
INSERT INTO TAB1 ( "Code" ,  "Name" ) VALUES ( 4 , '5555');
INSERT INTO TAB1 ( "Code" ,  "Name" ) VALUES ( 5 , '5555');


Необходимо подсчитать колво уникальных записей по полю Name

Сначала сделал такой запрос:

Код: plaintext
1.
2.
SELECT COUNT( "Name" ) FROM  "TAB1" 
GROUP BY  "Name" 


Результат соотв.:
2
1
2

получили запрос из 3 записей - что и ожидалось...
но как просто подсчитать их кол-во? (фетч не предлагать - там их оч. много)

перебрал уже все варианты, даже сумел положить сервер (1.5 релиз) таким вот запросом:
Код: plaintext
1.
2.
3.
4.
SELECT COUNT((
SELECT COUNT( "Name" ) FROM  "TAB1" 
GROUP BY  "Name" ))
FROM  "TAB1"  GROUP BY  1 


ЗЫ, COUNT на вьюв таки получилось, но в у меня в реальной задаче еще динамический where :(
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32438909
ZrenBy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
select count (distinct Name)
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32438999
Andrew Kruchinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот это?

select count("Code") from "TAB1"
where "Name" in
(
SELECT "Name" FROM "TAB1"
GROUP BY "Name"
having count("Name")=1)
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32439667
x.diablo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
select count(distinct  "Name" ) FROM  "TAB1" 


век живи - век учись...
огромное спасибо!
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32439894
x.diablo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
епт! только ж почему DISTINCT не использует индекс по Name ???
это даже тормознее, чем фетчить по моему запросу :(
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444484
x.diablo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мдя, придется, видимо, ХП делать, раз никто не знает :(
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444485
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну не факт что с индексом быстрее. Если записей в таблице очень много, то попробуй так:

Код: plaintext
SELECT COUNT(DISTINCT NAME) FROM TAB1 GROUP BY NAME
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444492
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А может мне кто-нибудь объяснить, почему этот запрос

SELECT COUNT(DISTINCT NAME) FROM TAB1

вообще должен использовать индекс и какой от индекса толк в данном случае . И не совсем
понятно как здесь может помочь ХП - разве в любом случае, не придется пробежаться по всем
записям? Спрашиваю не из желания поумничать - мне в самом деле не понятно.


2Gold
Мне кажется (могу ошибаться) ваш запрос вернет N-е количество едениц. Причем N будет равно значению count (distinct)
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444498
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я
2Gold
Мне кажется (могу ошибаться) ваш запрос вернет N-е количество едениц. Причем N будет равно
значению count (distinct)

Или имеется ввиду использовать данный запрос в ХП, а потом выполнить select count(*) для
этой процедуры?
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444508
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может я и торможу :-(
Тогда можно написать
Код: plaintext
SELECT COUNT(NAME) FROM TAB1 GROUP BY NAME
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444510
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>SELECT COUNT(NAME) FROM TAB1 GROUP BY NAME
Да это почти тоже, только вместо едениц будет содержать количество вхождений того
или иного name. Я в принципе не об этом - как здесь может быть использован индекс по name
если name не используется в условии where
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444512
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вернее так (извращение):

Код: plaintext
SELECT COUNT(*) FROM TAB1 WHERE NAME=ANY(SELECT NAME FROM TAB1 GROUP BY NAME)
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444513
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да что-то я затормозил. Я ещё хотел посоветовать
SELECT SUM(COUNT(...)) ...
и
SELECT COUNT(SELECT ...) ...

Хорошо вовремя остановился
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444517
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>SELECT COUNT(*) FROM TAB1 WHERE NAME=ANY(SELECT NAME FROM TAB1 GROUP BY NAME)
Да уж - по моему это еще медленее , чем просто select count(distinct))

Ладно, пойду я тоже спать - все равной мой вопрос игнорируют.
Пациент: Доктор, вы знаете, меня все игнорируют!
Доктор: Следующий!
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444781
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Somebody

Somebody>SELECT COUNT(NAME) FROM TAB1 GROUP BY NAME
как здесь может быть использован индекс по name если name не используется в условии where

NAME используется в GROUP BY, следовательно нужна сортировка. Она может быть выполнена навигацией по индексу (ORDER-план) или вычитыванием записей в буфер с последующей внешней сортировкой (SORT-план). С DISTINCT тоже самое - эффективно убрать дубликаты можно только в отсортированном наборе. Вот только в последних версиях (то ли с IB 5.6, то ли с IB 6.0) оптимизатор никогда не использует индексную навигацию для выполнения DISTINCT.
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444799
Andrew Kruchinin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dimitrВот только в последних версиях (то ли с IB 5.6, то ли с IB 6.0) оптимизатор никогда не использует индексную навигацию для выполнения DISTINCT.

Хм. А это как чревато? В смысле не вернуть ли все назад чтобы по индексам строил выборку. Или не нужно и тогда почему.

P.S. Кстати, а что там с конференцией? Подвисла?
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444879
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторХм. А это как чревато? В смысле не вернуть ли все назад чтобы по индексам строил выборку. Или не нужно и тогда почему.

Там нюансов много. Каждый раз, когда борманы это делали, всплывали новые баги. Пол-оптимизатора утыкано комментариями на эту тему :-) После того, как там затычка уже сидела на затычке, они отключили это нафиг.

Да и очевидных преимуществ это не даст в большинстве случаев. ORDER-план для сортировки (при условии полной выборки, т.е. fetch-all) становится эффективным при hit-ratio страничного кеша выше 90%, чтобы минимизировать потери на случайный доступ к записям. Внешняя сортировка же от эффективности кеша не зависит и приводит к замедлению только при уходе на диск (когда сортируемые объемы большие). Но в этом случае (большие объемы) ORDER-план просто убьет страничный кеш и тоже приведет к значительному I/O.

К GROUP BY это все тоже относится, но он все же чаще используется в fetch-first паттернах, чем DISTINCT, и поэтому его выгодно отображать на индекс, если это возможно.

авторP.S. Кстати, а что там с конференцией? Подвисла?

Вроде через гейт все работает.
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444911
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2dimitr

thks. Понятно. Т.е. сортировка используется в любом случае, если я правильно понял.
Проверял на таблице из порядка 172000 записей - count (distinct) визуально работает примерно
столько же времени как и group by, хотя в первом случае план натурал, а во втором используется
индекс соответствующего поля . Хотя может просто записей мало.

Ну и насчет

Gold
SELECT COUNT(*) FROM TAB1 WHERE NAME=ANY(SELECT NAME FROM TAB1 GROUP BY NAME)
Проверил (из любопытства) подобное на этой же таблице... Минут 20 IBConsole просто висела, а
затем я ее "убил"... Эх Gold, Gold
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32444966
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПроверил (из любопытства) подобное на этой же таблице... Минут 20 IBConsole просто висела, а затем я ее "убил"...

Это удивляет? ;-)

Код: plaintext
1.
2.
SELECT COUNT(*)
FROM TAB1
WHERE NAME = ANY (SELECT NAME FROM TAB1 GROUP BY NAME)


превращается сервером в:

Код: plaintext
1.
2.
SELECT COUNT(*)
FROM TAB1 T
WHERE EXISTS (SELECT NAME FROM TAB1 WHERE NAME = T.NAME GROUP BY NAME)


В результате, имеем коррелированный подзапрос, выполняющийся для каждой записи из TAB1. Вдобавок, этот подзапрос имеет абсолютно избыточную группировку. Ну и наконец, этим подсчитается просто число записей в TAB1 ;-)
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32445011
somebody
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2dimitr
>Это удивляет? ;-)
Да вобщем нет Но результат превзошел все ожидания
...
Рейтинг: 0 / 0
Можно ли такое сделать запросом?
    #32445281
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Э как меня вчера ночью прорвало на бред всякий :-) А всё пиво виновато :-)
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Можно ли такое сделать запросом?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]