Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: sql запрос (фильтрация повторов)  (Прочитано 50610 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 04-07-2007 10:21 » 

парюсь с одной вещью, а интуиция подсказывает, что наверняка есть стандартное решение.

постановка задачи (упрощённо): имеется таблица T, в которой следующие поля
I - уникальный индекс
N - номер объекта
F - некий признак (==1 или ==0)

скажем, таблица содержит такие данные (для наглядности отсортировал по номеру)
Код:

 I  N  F
 0  1  1
 1  1  0
 2  1  1
 3  1  1
 4  2  0
 5  2  1
 6  2  1
 7  3  0
 8  3  0
 9  3  0

требуется сделать один запрос , чтобы потом пробежаться по результату, и определить, у каких объектов установлен признак F хотя бы в одной записи.

делаю запрос
select  N  from T  where F=1

получаю результат
Код:

 I  N  F
 0  1  1
 2  1  1
 3  1  1
 5  2  1
 6  2  1

таким образом, если объект хоть раз встретился в _Результате_, то признак у этого объекта считается установленным.

А теперь вопрос: как составить SQL-запрос, чтобы записи с одним и тем же номером объекта не повторялись (поскольку достаточно самой первой записи с установленным признаком), то есть результат запроса был бы такой

Код:

 I  N  F
 0  1  1
 5  2  1

спасибо заранее...
« Последнее редактирование: 05-07-2007 12:53 от Алексей1153++ » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-07-2007 10:30 » 

distinct в помощь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 04-07-2007 10:32 » 

поспешил Улыбаюсь

select distinct  N  from T  where F=1

выберет только N неповторяющиеся

а более сложное, а именно как ты привел в результате

Код:
 I  N  F
 0  1  1
 5  2  1

надо городить сложный запрос, потому как записи  не повторяются
« Последнее редактирование: 04-07-2007 10:43 от Sla » Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 04-07-2007 10:33 » 

а как им тут воспользоваться ? Номер то как бы и так отсортирован...
Записан

McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #4 : 04-07-2007 10:33 » 

select distinct  N  from T  where F=1;
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 04-07-2007 10:37 » 

McZim, не, это проблему не решает. Не в сортировке же дело, а в лишних записях в выборке. А сама сортировка - по барабану, если честно

-
ой, или сам туплю )) Это же не сортировка,
Это похоже и есть, что надо ) , щас опробую
« Последнее редактирование: 04-07-2007 10:41 от Алексей1153++ » Записан

McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #6 : 04-07-2007 10:39 » 

Алексей1153++, а никто про сортировку и не говорит, distinct --это фильтрация дубликатов. Можно еще добавить where exists, тогда при получении первой записи удовлетворяющую условиям выборки, дальше записи не будут рассматриваться!
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 04-07-2007 10:44 » 

McZim,Sla, всё, кажись, работает, спасиб )

а насчёт where exists поподробнее
Записан

McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #8 : 04-07-2007 10:59 » 

Если нужно видеть только уникальные имена, то запрос будет работать так как ты его напишеш, но можно повысить его эффективность, если переписать его так:

select N from T
        where exists (F=1)

Причина более быстрой отработки запроса в том, что предложение EXISTS возвратит имя сразу же, когда найден первое значение, и никакие другие значения далее не будут сканироваться. А DISTINCT будет сканировать весь список и отсекать повторяющиеся значения, тем самым запрос будет выполняться долбше.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 04-07-2007 11:11 » 

не выходит с exists , идёт почему то ругань на F
Записан

McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #10 : 04-07-2007 11:24 » 

тогда where exists (здесь нужно поместить еще один запрос Select)
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #11 : 04-07-2007 11:24 » 

Алексей1153++, если у тебя база не большая, толда и не нужно заморачиваться используй только distinct
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 04-07-2007 11:43 » 

база не большая, она БОЛЬШАЯ Улыбаюсь

distinct уже вроде катит, пользуюсь им )
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #13 : 04-07-2007 11:52 » 

Цитата
А теперь вопрос: как составить SQL-запрос, чтобы записи с одним и тем же номером объекта не повторялись (поскольку достаточно самой первой записи с установленным признаком), то есть результат запроса был бы такой
Код:
 I  N  F
 0  1  1
 5  2  1
Леш, а зачем тебе в recordset столбци I и F? I столбец не совсем корректен, A F всегда будет равен 1.

А так мое решение Улыбаюсь
Код:
select I, N, 1 from Alex1153 where f=1 group by N;
« Последнее редактирование: 04-07-2007 11:59 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 04-07-2007 12:02 » 

Finch, зачем изо мну-то записи извлекать ? )))

а
I, N, 1  - что означать будет единица ?
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #15 : 04-07-2007 12:11 » 

Леш, это я создавал твою таблицу у себя в базе данных. Вот чтоб потом не мучится в сомнениях "нафига". Таблицу обозвал в честь тебя Улыбаюсь

У тебя по любому столбец F ,будет равен 1. Вот я и с оптимизировал. Заместо переменной, вставил константу. Хотя если действовать до конца по твоему тех заданию, нужно писать так:
Код:
select I, N, 1 as F from Alex1153 where f=1 group by N;
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 04-07-2007 12:21 » 

я так понимаю, что I это id записи, и нужно только N
если это так, то distinct в руки

если нет, а I нужно еще для чего-то, то надо городить  сложные запросы, ну а лучше тогда уж пробегать курсором
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 04-07-2007 13:04 » 

Финч, всё равно загадками говоришь ) Я, по крайней мере, запутался в твоём запросе.
I - выбирать не требуется, почему 1 в начале запроса я так и не понял...
И как бы группировать по N зачем ?

Слава, да, I это id записи . Сложные запросы не катят, почему то их связка ODBC+FireBird не воспринимает никак (понимает лишь простые команды - лежать, сидеть) , а переделывать проект под другое не хочется и долго это.
« Последнее редактирование: 04-07-2007 13:07 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 05-07-2007 04:16 » 

Финч, твой вариант работает (кстати, открыл для себя новую фишку - создание дополнительных столбцов в результате запроса Улыбаюсь  Например некий столбец  zzz
select ..., A+B as zzz  ...
 -уже всё подсчитано, и ваще жись прекрасна Улыбаюсь) )

по скорости работы пока я не разобрался.

единственное я не понял, почему, если убрать group, то записи повторяются, а с group - не повторяются ?..
« Последнее редактирование: 05-07-2007 04:42 от Алексей1153++ » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 05-07-2007 06:17 » 

(кстати, открыл для себя новую фишку - создание дополнительных столбцов в результате запроса Улыбаюсь  Например некий столбец  zzz
select ..., A+B as zzz  ...
 -уже всё подсчитано, и ваще жись прекрасна Улыбаюсь) )

Ну ты даешь Улыбаюсь
Ты что считал, что SQL это цацки-пецки?
Или ты не видел запросов типа
Код:
SELECT     x.Id, x.CalcId, x.AccessFlag, 
                           (SELECT     Code
                            FROM          Users u
                            WHERE      u.Id = x.CreatorId) AS CreatorCode,
                          (SELECT     Name
                            FROM          Users u
                            WHERE      u.Id = x.CreatorId) AS CreatorName
FROM         Tr WITH (NOLOCK, FASTFIRSTROW) x INNER JOIN
                 .....
WHERE    .....
                      AND EXISTS
                          (SELECT     1
                            FROM          Visible v
                            WHERE      v.UserId = x.CreatorId AND v.OwnerId = u.Id)
                            HAVING      (MAX(i.IsDebitView) = 1 OR
                                                   (x.CreatorId = u.Id AND MAX(i.IsDebit) = 1)) AND MAX(i.IsDebitView) <> 2)
               ....
Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #20 : 05-07-2007 06:28 » 

единственное я не понял, почему, если убрать group, то записи повторяются, а с group - не повторяются ?..

и не удивительно, ты же группируешь по N, соответсвенно если он несколько раз встретит одно и то же число, как он будет группировать? Да еще поди ты distinct'ом все отфильтровал!! Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 05-07-2007 08:53 » 

Sla, про такие многоэтажные запросы я в курсе, но сталкиваться не приходилось ни разу )

McZim, не, distinct там уже не было. И всё же навопрос ответа нету - почему, если убрать group, то записи повторяются, а с group - не повторяются ? Улыбаюсь
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 05-07-2007 10:17 » 

приведи пример с group by и без
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Oldy
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 05-07-2007 10:26 » 

Группировка по полю (значению, типу и т.п.). Так distinct тебе покажет, что в таблице есть строки где N=x и F=1, а вот чтобы посчитать, сколько их там с каждым N, придется попотеть. С group же это легче, чтото вроде -
select I, N, F, count(N) as R from T where F=1 group by N
Записан

С уважением, Oldy.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 05-07-2007 11:36 » 

Oldy, Sla, мммм,   условие задачи - не подсчитать число записей, где N==x и F==1 ,  а определить факт, что хотя бы у одной записи, где N==x, признак F==1 Улыбаюсь

Sla, без group -

select I, N, 1 from Alex1153 where f=1

 N  F
 1  1
 1  1
 1  1
 2  1
 2  1

с ним -
select I, N, 1 from Alex1153 where f=1 group by N

 N  F
 1  1
 2  1
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 05-07-2007 12:10 » 

Алексей1153++, ты чего-то темнишь, а где же I в выборке?
и что это там за 1 от финча? Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #26 : 05-07-2007 12:15 » 

Алексей1153++, я же тебе говорю, group by группирует вывод результата, соостветсвенно если есть повторяющиеся значения, он их показывать не станет, так как группирует по уникальнонму значению. Надеюсь понятно изъяснил... Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 05-07-2007 12:40 » 

select N from T where F=1 group by N
==
select distinct N from T where F=1

select I, N from T where F=1 group by N          работать не будет - I меняется
 
select N, 1 from T where F=1 group by N работать будет
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 05-07-2007 12:52 » 

Sla, McZim, вот, теперь я понял )

но потом ещё вопросы наверное будут, почти обешшаю )
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #29 : 05-07-2007 19:51 » 

Sla,
Цитата
select I, N from T where F=1 group by N          работать не будет - I меняется
Этот запрос в MySQL работает. И насколько я помню MSSQL ее тоже нормально кушает. Просто в I , будет записано первое попавшейся значение, удовлетворяюшее условию.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines