Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Left join not in 
:(
    Опции темы
gelo86
Дата 28.9.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Допустим у меня есть две таблицы: 
Код

  User(id) / Read_books(user_id, book_name).


Есть такие записи:
Код

User     Read_books
1           1,   'Name1'
2           1,   'Name2'
3           2,   'Name3'


Как мне вытенуть людей, каторие нечитали книжки с именем Name2 ? Left join мне вернет человека с id=1, так как он имеет есчо запись с книжкой под названием 'Name1'.




PM MAIL   Вверх
ТоляМБА
Дата 28.9.2009, 19:30 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Котэ
***


Профиль
Группа: Завсегдатай
Сообщений: 1607
Регистрация: 15.12.2004

Репутация: 4
Всего: 252



Методом исключения:

Код
Select *
From User
where user.id not in
(select Read_books.user_id
from Read_books
where book_name='Name2')


Если не пойдет, то после закрывающей скобки допиши 'AS a'.

PM   Вверх
gelo86
Дата 28.9.2009, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



1. У меня около 30000 людей, и если половина из них прочитали ету книжку, то получится что в not in будет около 15000 идишников (а как слишал not in при таких количествах неочень оптимальный).

2. Да и селект : 
Код
select Read_books.user_id from Read_books where book_name='Name2'
 небудет выполняться для каждого человека 
Код
Select * From User where user.id not in
 ?

Это сообщение отредактировал(а) gelo86 - 28.9.2009, 19:34
PM MAIL   Вверх
Zloxa
Дата 28.9.2009, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161




M
Zloxa
Перенесено из баз данных



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Gluttton
Дата 28.9.2009, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Код

select id
from user
    inner join read_books
    on user.id=read_books.user_id
    where read_books.user_id not in
    (
        select distinct user_id
        from read_books
            where book_name='Name2'
    )



--------------------
Слава Україні!
PM MAIL   Вверх
gelo86
Дата 28.9.2009, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Цитата(Gluttton @ 28.9.2009,  19:37)
Код

select id
from user
    inner join read_books
    on user.id=read_books.user_id
    where read_books.user_id not in
    (
        select distinct user_id
        from read_books
            where book_name='Name2'
    )

Та же проблема с not in. Я понемаю, что может и нету другого способа. А как ви относитесь к: not in(1..15000) ?
PM MAIL   Вверх
Gluttton
Дата 28.9.2009, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



СУБД? Например счастливые пользователи Oracle могут воспользоваться предложением MINUS...


--------------------
Слава Україні!
PM MAIL   Вверх
gelo86
Дата 28.9.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Исползуется Oracle, но пишем на Java + Hibernate => HQL, поетому думаю MINUS в HQL непрокатит :(
PM MAIL   Вверх
boevik
Дата 28.9.2009, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: нет
Всего: 35



Можно конечно совсем без not in, 
Код

select t1.id from user t1 left join
(select user_id from read_books where name = 'book1') t2
on t1.id =t2.user_id
where t2.user_id is null





--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
gelo86
Дата 28.9.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Цитата(boevik @ 28.9.2009,  19:49)
Можно конечно совсем без not in, 
Код

select t1.id from user t1 left join
(select user_id from read_books where name = 'book1') t2
on t1.id =t2.user_id
where t2.user_id is null

А СУБД внутренний селект будет виполнять толко один раз ?
PM MAIL   Вверх
Gluttton
Дата 28.9.2009, 19:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Вот тут  написано про про разность и некоторые варианты его реализации...


--------------------
Слава Україні!
PM MAIL   Вверх
boevik
Дата 28.9.2009, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: нет
Всего: 35



Цитата(gelo86 @  28.9.2009,  19:53 Найти цитируемый пост)

А СУБД внутренний селект будет виполнять толко один раз ? 

Да, так как не зависит от внешних параметров.


--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
Zloxa
Дата 28.9.2009, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



boevik, 
Тогда уж лучше
Код

select /*distinct*/ t1.id 
  from user t1 
  left join read_books t2 on name = 'book1' and t1.id =t2.user_id
where t2.user_id is null

disitnct раскоментировать, если пара user_id,name не уникальна.

ну и еще несколько вариаций
Код

select * from user where not exists (select null from read_books where read_books.user_id = user.id and name = 'book1')

select id from user
minus
select user_id from read_books where name = 'book1'

select * from user where id in (select user_id from user_books where name != 'book1')


Цитата(gelo86 @  28.9.2009,  19:32 Найти цитируемый пост)
а как слишал not in при таких количествах неочень оптимальный

Веский аргумент. smile 


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
gelo86
Дата 28.9.2009, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 388
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Для чего нужен: 
Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
where t2.user_id is null
 ?

PM MAIL   Вверх
boevik
Дата 28.9.2009, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: нет
Всего: 35



Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
Тогда уж лучше

Код

select /*distinct*/ t1.id 
  from user t1 
  left join read_books t2 on name = 'book1' and t1.id =t2.user_id
where t2.user_id is null

disitnct раскоментировать, если пара user_id,name не уникальна.

Вполне возможно что и этот вариант пройдет. (не совсем помню как поведет себя name = 'book1' внутри on)

Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
Код

select * from user where not exists (select null from read_books where read_books.user_id = user.id and name = 'book1')

В этом случае на каждую запись в таблице user выполняется внутрений select, если есть индекс то может и не страшно, а если нет, то ...

Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
Код

select id from user
minus
select user_id from read_books where name = 'book1'

минус не все СУБД поддерживают.



Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
Код

select * from user where id in (select user_id from user_books where name != 'book1')

совсем не верный результат вернет.

Добавлено через 8 минут и 13 секунд
Цитата(gelo86 @ 28.9.2009,  20:11)
Для чего нужен: 
Цитата(Zloxa @  28.9.2009,  20:08 Найти цитируемый пост)
where t2.user_id is null
 ?

показать только теx пользователей из t1 которые не присуствуют в t2


--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0655 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.