Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Добрый день.
Возник вопрос.

Есть таблица my_table.

В таблице есть поля id, flag, person....

Для каждого person может быть несколько строк с различными значениями flag.

Требуется сделать выборку person, у которых есть flag = 4, но нет флагов = 1,48,34 и 9.

Как бы это сделать?

Обычно я использую внешнее объединение, если требуется найти с флагом 4, но без флага 1 (пример).

но ведь тогда сейчас будет 4 внешних объединения..... На сколько это плохо? таблица содержит огроменное количество строк!

Посоветуйте, пожалуйста.
22 фев 07, 11:56    [3821277]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Хм..
Guest
это плохо.. лучше так
select * from my_table t
where t.flag=4
  and not exists
      (select * from my_table tt
        where tt.peron=t.person
          and tt.flag not in (1,48,34, 9))
22 фев 07, 12:16    [3821431]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Михаил Панайот
Member

Откуда:
Сообщений: 17
Например,
select person
from my_table
where flag in (4, 1, 48, 34, 9)
group by person
having sum( decode( flag, 4, -1, 1 )) = -1
22 фев 07, 12:21    [3821479]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Elic
Member

Откуда:
Сообщений: 29991
select person from my_table
  group by person
  having count(case when flag in (4)         then 0 end) > 0
     and count(case when flag in (1,48,34,9) then 0 end) = 0
22 фев 07, 12:21    [3821480]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Всем спасибо за варианты. Попробую.

Вот только этот (заранее знаю) висит очень-очень долго и я так и не дождалась его выполнения.... А тот, что я предложила отрабатывает за 10 минут.

Хм..
это плохо.. лучше так
select * from my_table t
where t.flag=4
  and not exists
      (select * from my_table tt
        where tt.peron=t.person
          and tt.flag not in (1,48,34, 9))
22 фев 07, 12:50    [3821785]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Wladislaw
Member

Откуда:
Сообщений: 245
Eva_2006
Всем спасибо за варианты. Попробую.

Вот только этот (заранее знаю) висит очень-очень долго и я так и не дождалась его выполнения.... А тот, что я предложила отрабатывает за 10 минут.

Хм..
это плохо.. лучше так
select * from my_table t
where t.flag=4
  and not exists
      (select * from my_table tt
        where tt.peron=t.person
          and tt.flag not in (1,48,34, 9))


Ну положим этот запрос и отрабатывает неверно :). Not перед in лишний.
22 фев 07, 12:55    [3821834]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Elic
Member

Откуда:
Сообщений: 29991
Eva_2006
Вот только этот (заранее знаю) висит очень-очень долго и я так и не дождалась его выполнения....
ХЕЗ, какие у тебя там индексы есть :)
Eva_2006
А тот, что я предложила отрабатывает за 10 минут.
Eva_2006
Обычно я использую внешнее объединение, если требуется найти с флагом 4, но без флага 1 (пример).
Ну так и используй одно + группировку:
on ... and flag in (1,48,34,9)
22 фев 07, 13:05    [3821923]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Хм..
Guest
2 Wladislaw: и то правда :)
2 Eva2006: если приведенная структура таблицы соответсвует действительной никак не может то что вы предложили отрабатывать быстрее того что я.. раза в два так.. или вы что-то скрываете?
22 фев 07, 13:12    [3821971]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Elic
ХЕЗ, какие у тебя там индексы есть :)

Eva_2006
Обычно я использую внешнее объединение, если требуется найти с флагом 4, но без флага 1 (пример).
Ну так и используй одно + группировку:
on ... and flag in (1,48,34,9)


Elic, конечно, я привела не всю структуру. В действительности она намного сложнее.

Вопрос: А как при внешнем объединении использовать flag in (1,48,34,9)? Это ведь будет внешнее объединение, а значит после flag нужно ставить +, а плюс в данных выражениях недопустим... Или я опять не поняла?
22 фев 07, 13:43    [3822305]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Elic
Member

Откуда:
Сообщений: 29991
Eva_2006
А как при внешнем объединении использовать flag in (1,48,34,9)? Это ведь будет внешнее объединение, а значит после flag нужно ставить +, а плюс в данных выражениях недопустим... Или я опять не поняла?
Никогда не слышала про ansi-join-ы? :)
Для не-ansi-join-ов STFF Что делает конструкция (+) ???
22 фев 07, 13:52    [3822391]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Elic
Eva_2006
А как при внешнем объединении использовать flag in (1,48,34,9)? Это ведь будет внешнее объединение, а значит после flag нужно ставить +, а плюс в данных выражениях недопустим... Или я опять не поняла?
Никогда не слышала про ansi-join-ы? :)
Для не-ansi-join-ов STFF Что делает конструкция (+) ???


а в чем отличие ansi-join ?

Если не ошибаюсь, то это LEFT, RIGHT, GROSS JOIN, INNER JOIN... или нет?
22 фев 07, 14:42    [3822857]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Так, кажется поняла. В ANSI больше возможностей :)
22 фев 07, 14:57    [3822995]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Подскажите дурочки, что не так :(

SELECT 	/*+  full(ds) full(ds2) parallel(ds,4) parallel(ds2,4)*/
			
	count(*)
			
  	FROM 
	  		service ds	LEFT JOIN service ds2
	  		on ds.id = ds2.id
  	     
  	where 	1 = 1

                          and ds.serv_id = 5
  		and ds2.serv_id in (14, 8, 2, 8993)
			     
  			and sysdate between ds.df and nvl(ds.dt, sysdate)
  			and sysdate between ds2.df and nvl(ds2.dt, sysdate)

  			and ds.date_from < trunc(sysdate)-100

Вообще в идеале после выборки должен быть отбор только строк, у которых ds2.id = null

Вот только запрос работает как-то не так.... После выборки из первой таблицы получается 590 000 записей.

А в результате данного запроса (после объединения таблиц) только 50 000.... Я в растерянности...
22 фев 07, 16:10    [3823588]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Elic
Member

Откуда:
Сообщений: 29991
Eva_2006
Подскажите дурочки, что не так :(
Своей "безграмотностью" ты оскорбляешь всех нас :)
Eva_2006
Вообще в идеале после выборки должен быть отбор только строк, у которых ds2.id = null
Естественно, это условие должно быть в where.
Eva_2006
Вот только запрос работает как-то не так...
Потому что ты не смогла списать любезно предосталенную тебе часть условия соединения таблиц :)
22 фев 07, 16:22    [3823694]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Elic, спасибо вам огромное. Вы меня всегда выручаете :) и я всегда надеюсь на вас.
И извините за ошибочки.... Спасибо....
22 фев 07, 16:25    [3823721]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Все-таки решила еще раз уточнить.

Вот так нужно было?

SELECT 	/*+  full(ds) full(ds2) parallel(ds,4) parallel(ds2,4)*/
			
	count(*)
			
  	FROM 
	  		service ds	LEFT JOIN service ds2
	  		on ds.id = ds2.id and ds2.serv_id in (14, 8, 2, 8993)
  	     
  	where 	1 = 1

            and ds.serv_id = 5
    
  			and sysdate between ds.df and nvl(ds.dt, sysdate)
  			and sysdate between ds2.df and nvl(ds2.dt, sysdate)

  			and ds.date_from < trunc(sysdate)-100
  			and ds2.terminal_device_id is null
26 фев 07, 09:37    [3830847]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
В прошлом сообщении сделала опечаточку:

Вот так нужно было?

SELECT 	/*+  full(ds) full(ds2) parallel(ds,4) parallel(ds2,4)*/
			
	count(*)
			
  	FROM 
	  		service ds	LEFT JOIN service ds2
	  		on ds.id = ds2.id and ds2.serv_id in (14, 8, 2, 8993)
  	     
  	where 	1 = 1

            and ds.serv_id = 5
    
  			and sysdate between ds.df and nvl(ds.dt, sysdate)
  			and sysdate between ds2.df and nvl(ds2.dt, sysdate)

  			and ds.df < trunc(sysdate)-100
  			and ds2.id is null
[/quot]
26 фев 07, 09:52    [3830896]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Но этот запрос работает уже 40 минут .... и не известно сколько еще висеть будет....
26 фев 07, 10:31    [3831067]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
givanov
Member

Откуда:
Сообщений: 757
Eva_2006
Вот так нужно было?
Видимо нет.
Не могли бы Вы еще раз сформулировать задачу и привести описания таблиц? А то не совсем понятно, какие флаги должны быть, каких не должно и как они храняться в базе.
26 фев 07, 10:44    [3831129]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Существует таблица service c огроменным количеством строк!

Структура таблицы:
id1 - уникальный идентификатор строки
id
flag
df - начальная дата
dt - конечная дата или null

Нужно выбрать все id (без повторения), у которых есть flag = 5 (конечная дата пустая), но нет флагов 2,6,3,7 ( конечная дата в прошлом, либо вообще не было записи)
26 фев 07, 10:57    [3831183]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
givanov
Member

Откуда:
Сообщений: 757
А это что?
serv_id in (14, 8, 2, 8993)
26 фев 07, 11:03    [3831216]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Извините, serv_id - это и есть flag. Запуталась в обозначениях.... В реальности названия очень длинные и я их для форума сократила....
26 фев 07, 11:08    [3831242]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
givanov
Member

Откуда:
Сообщений: 757
Тогда да, похоже что все правильно.
Если хинты убрать и тоже долго получится - нужно будет планы смотреть.
SELECT count(*)
  FROM service ds
       LEFT JOIN service ds2
          on ds.id = ds2.id
         and ds2.serv_id in (14, 8, 2, 8993)
         and ds2.dt < sysdate
  where ds.serv_id = 5
    and sysdate between ds.df and nvl(ds.dt, sysdate)
    and ds.df < trunc(sysdate)-100
    and ds2.id is null
26 фев 07, 11:16    [3831291]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
спасибо. попробую
26 фев 07, 11:19    [3831321]     Ответить | Цитировать Сообщить модератору
 Re: Выборка на основе данных одной таблицы  [new]
Eva_2006
Member

Откуда:
Сообщений: 256
Попробовала. За 40 минут не отработал. Оборвала сессию :(
26 фев 07, 11:55    [3831575]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить