Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Правильно ли писать такие вложеные запросы по выборке / 25 сообщений из 34, страница 1 из 2
03.02.2009, 00:13
    #35792691
Остап Ибрагимович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Привет!
Вот есть такой запрос, например

Код: plaintext
SELECT * FROM TAB1 WHERE USERID IN (SELECT USERID FROM TAB2 WHERE ORDERSID IN (SELECT ORDERSID FROM TAB3 WHERE NAME = @NAME))

можно ли так их писать, а Sql у меня опыта такого большого нету.... (select * from .... )))) вот и спрашиваю...

Спасибо!

З.Ы. такой запрос кстати выводит, то что мне нужно... но я так полагаю, он не совсем правиль или коректно написан, да?
Мда...Это не Рио Дежанейро!
...
Рейтинг: 0 / 0
03.02.2009, 02:54
    #35792756
AAron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
возможно, использование exists конструкции увеличит скорость запроса.
а вообще, надо в профильный форум - Oracle, SQL Server и т.п.
...
Рейтинг: 0 / 0
03.02.2009, 09:03
    #35792893
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Остап Ибрагимовично я так полагаю, он не совсем правиль или коректно написан, да?Это можно понять, посмотрев план выполнения запроса.
...
Рейтинг: 0 / 0
03.02.2009, 11:44
    #35793339
Остап Ибрагимович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Алексей К,

Запросто то как раз и выводит все то что и нужно... но сам запрос, мне так кажется не красиво написан...
...
Рейтинг: 0 / 0
03.02.2009, 12:26
    #35793472
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Остап Ибрагимовично сам запрос, мне так кажется не красиво написан...Ну напишите красиво :-))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT * 
FROM TAB1 
WHERE 
    USERID IN 
    (
        SELECT USERID 
        FROM TAB2 
        WHERE 
            ORDERSID IN 
            (
                SELECT ORDERSID 
                FROM TAB3 
                WHERE NAME = @NAME
            )
    )
Тут главное, чтобы оптимизатор понял, чего Вы от него хотите. :-))
...
Рейтинг: 0 / 0
03.02.2009, 14:53
    #35794024
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Правильно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT * 
FROM 
     TAB1 
        INNER JOIN
     TAB2 
       ON 
     TAB1.UserId = Tab2.UserId
        INNER JOIN
     TAB3
        ON
     TAB2.ORDERSID = TAB3.ORDERSID 
WHERE
         NAME = @NAME
...
Рейтинг: 0 / 0
03.02.2009, 15:27
    #35794153
Остап Ибрагимович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVaПравильно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT * 
FROM 
     TAB1 
        INNER JOIN
     TAB2 
       ON 
     TAB1.UserId = Tab2.UserId
        INNER JOIN
     TAB3
        ON
     TAB2.ORDERSID = TAB3.ORDERSID 
WHERE
         NAME = @NAME


Вот типа такого я и имел ввиду...
Спасибо!
...
Рейтинг: 0 / 0
03.02.2009, 15:33
    #35794181
AAron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
отнюдь неправильно, запрос возвращает больше данных, чем первоначальный.
да и работать может медленее/быстрее, чем первый.
...
Рейтинг: 0 / 0
03.02.2009, 15:40
    #35794209
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa

тынць
_________________
"Helo, word!" - 17 errors 56 warnings
...
Рейтинг: 0 / 0
03.02.2009, 23:21
    #35795167
SQL_Lamer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Остап Ибрагимович,
Вложенные запросы или join-ы - и так и так правильно.
...
Рейтинг: 0 / 0
04.02.2009, 01:04
    #35795234
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SQL_Lamer
Вложенные запросы или join-ы - и так и так правильно

Отнюдь:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
create table TT1
(
    Id int,
    Val varchar( 256 )
)
go

insert into TT1 (Id, Val) values ( 1 ,'TT1_1')
insert into TT1 (Id, Val) values ( 2 ,'TT1_2')
go

create table TT2
(
    Id int,
    TT1_Id int,
    FInt int null
)
go

insert into TT2 (Id, TT1_Id, FInt) values ( 1 ,  1 ,  10 )
insert into TT2 (Id, TT1_Id, FInt) values ( 2 ,  1 ,  20 )
insert into TT2 (Id, TT1_Id, FInt) values ( 3 ,  1 ,  30 )
insert into TT2 (Id, TT1_Id, FInt) values ( 4 ,  2 ,  100 )
insert into TT2 (Id, TT1_Id, FInt) values ( 5 ,  2 ,  200 )
insert into TT2 (Id, TT1_Id, FInt) values ( 6 ,  2 ,  300 )
go
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select
   *
from
   TT1 T1
   join TT2 T2 on (T2.TT1_Id=T1.Id)

select
   *
from
   TT1 T1
where
   T1.Id in (select T2.TT1_Id from TT2 T2 where T2.TT1_Id=T1.Id)

(ключевые слова: декартово произведение , distinct )

________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 11:42
    #35795807
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Формально вложенные запросы и join аналогичны,но использование первого, в таком варианте однозначно говорит о незнании sql(Ex_Soft, убери where в своем запросе).Любителям exists, следует учесть, что это - Self-Join, в общем варианте будут разные результирующие наборы.
...
Рейтинг: 0 / 0
04.02.2009, 12:39
    #35796015
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa
убери where в своем запросе

Убрать ГДЕ?
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 12:53
    #35796083
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa
Формально вложенные запросы и join аналогичны

Да?.. А я всю жизнь думал, что join - это декартово произведение ДВУХ таблиц со всеми вытекающими. А вложенный запрос, это выборка из ОДНОЙ таблицы записей, удовлетворяющих условию подзапроса. А оно вишь как...
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 13:34
    #35796228
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Код: plaintext
1.
2.
3.
4.
5.
6.
select
   *
from
   TT1 T1
where
   T1.Id in (select TT1_Id from TT2) 
Джойны разные бывают.Декартовое произведение - CROSS JOIN
...
Рейтинг: 0 / 0
04.02.2009, 14:18
    #35796461
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa
Джойны разные бывают

Гм... Повторяю то, что хочу донести:
Ex_Soft
А я всю жизнь думал, что join - это декартово произведение ДВУХ таблиц со всеми вытекающими. А вложенный запрос, это выборка из ОДНОЙ таблицы записей, удовлетворяющих условию подзапроса.

Т.е.: запрос с вложенным запросом
Код: plaintext
1.
2.
3.
4.
5.
6.
  SELECT *
        FROM Orders
        WHERE snum =
            ( SELECT snum
                 FROM Salespeople
                 WHERE sname = 'Motika')
http://www.sql.ru/docs/sql/u_sql/ch10.shtml
мы могли бы просто напечатать WHERE snum = 1004

Код: plaintext
1.
2.
3.
  SELECT *
        FROM Orders
        WHERE snum =  1004 
И Вы хотите сказать, что это " формально аналогично join'у "?
join (не важно какой) уже предполагает соединение двух и более таблиц, а это уже, IMHO, совсем другое, чем обычная выборка из одной таблицы по условию (пусть даже описанном во вложенном запросе). Ессесно речь о коррелированном/соотнесенном подзапросе не идет.
Вот, будьте любезны, если уж join и вложенный запрос аналогичны, можете привести запрос с join'ом без distinct, который в выше указанной дрозофиле вернет две строки, как в случае с вложенным запросом? А еще лучше - дайте тынць на источник этого утверждения.
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 16:17
    #35796992
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Не понял вопрос.
Источник один - посмотри план выполнения
Вместо
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT *
        FROM Orders
        WHERE snum =
            ( SELECT snum
                 FROM Salespeople
                 WHERE sname = 'Motika')
выполнит
Код: plaintext
1.
2.
SELECT *
        FROM Orders INNER JOIN  Salespeople ON   snum =  snum AND sname = 'Motika'
...
Рейтинг: 0 / 0
04.02.2009, 17:34
    #35797287
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa
посмотри план выполнения

Код: plaintext
1.
2.
3.
4.
5.
6.
select
    *
from
    TT1 T1
where
    T1.Id=(select T2.TT1_Id from TT2 T2 where T2.Id= 2 )

QUERY PLAN FOR STATEMENT 1 (at line 1).


STEP 1
The type of query is SELECT.

4 operator(s) under root

|ROOT:EMIT Operator
|
| |SEQUENCER Operator has 2 children.
| |
| | |SCALAR AGGREGATE Operator
| | | Evaluate Ungrouped ONCE AGGREGATE.
| | |
| | | |SCAN Operator
| | | | FROM TABLE
| | | | TT2
| | | | T2
| | | | Using Clustered Index.
| | | | Index : pkTT2
| | | | Forward Scan.
| | | | Positioning by key.
| | | | Keys are:
| | | | Id ASC
| | | | Using I/O Size 2 Kbytes for index leaf pages.
| | | | With LRU Buffer Replacement Strategy for index leaf pages.
| | | | Using I/O Size 2 Kbytes for data pages.
| | | | With LRU Buffer Replacement Strategy for data pages.
| |
| | |SCAN Operator
| | | FROM TABLE
| | | TT1
| | | T1
| | | Using Clustered Index.
| | | Index : pkTT1
| | | Forward Scan.
| | | Positioning by key.
| | | Keys are:
| | | Id ASC
| | | Using I/O Size 2 Kbytes for index leaf pages.
| | | With LRU Buffer Replacement Strategy for index leaf pages.
| | | Using I/O Size 2 Kbytes for data pages.
| | | With LRU Buffer Replacement Strategy for data pages.

другими словами

( sequence ( scalar_agg ( i_scan pkTT2 ( table ( T2 TT2 ) ) ) ) ( i_scan pkTT1 ( table ( T1 TT1 ) ) ) ) ( prop ( table ( T2 TT2 ) ) ( parallel 1 ) ( prefetch 2 ) ( lru ) ) ( prop ( table ( T1 TT1 ) ) ( parallel 1 ) ( prefetch 2 ) ( lru ) )

это на
select @@version
Adaptive Server Enterprise/15.0.2/EBF 14332/P/NT (IX86)/Windows 2000/ase1502/2486/32-bit/OPT/Thu May 24 04:10:36 2007

И на Firebird 2.0 WI-V6.3.3.12981

Plan
PLAN (T2 NATURAL)
PLAN (T1 INDEX (PKT1))

Adapted Plan
PLAN (T2 NATURAL) PLAN (T1 INDEX (PKT1))

никаких join'ов...
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 18:53
    #35797562
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Осталось еще и для join планы показать
...
Рейтинг: 0 / 0
04.02.2009, 19:15
    #35797608
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
SeVa
Осталось еще и для join планы показать

смысл? join даст join. Это - не неожиданно. А, вот, как
SeVa
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT *
         FROM Orders
         WHERE snum =
             ( SELECT snum
                  FROM Salespeople
                  WHERE sname = 'Motika')
выполнит
Код: plaintext
1.
2.
SELECT *
         FROM Orders INNER JOIN  Salespeople ON   snum =  snum AND sname = 'Motika'

Это для меня - новость. Вот я и хочу, так сказать, научную базу сего факта...
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 19:35
    #35797640
AAron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
какая научная база? SQL оперирует множествами. Оптимизатор операции на двух и более множествах так или иначе преобразует в join'ы, т.к. других способов объединить множества у него нет (кроме union).

например
Код: plaintext
select * from tbl1 where id in (select id from tbl2)
вырождается в обычный inner join. скорее всего он будет полносьтю эквивалентен запросу
Код: plaintext
select tbl1.* from tbl1 inner join tbl2 on tbl2.id = tbl1.id

запрос
Код: plaintext
select * from tbl1 where exists (select * from tbl2 where tbl1.id = tbl2.id)
также преобразуется к inner join, но немного более сложному и может работать значительно быстрее при наличии подходящего уникального индекса.

запрос, приведенный SeVa - ошибочен:
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT *
         FROM Orders
         WHERE snum =
             ( SELECT snum
                  FROM Salespeople
                  WHERE sname = 'Motika')
точнее, содержит потенциальную ошибку. в подзапросе может вернуться более одной строки. Для SQL Server 7.0+ это совершенно точно вызовет ошибку. для других СУБД возможно тоже.
...
Рейтинг: 0 / 0
04.02.2009, 19:55
    #35797671
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
авторexists также преобразуется к inner join, но немного более сложному и может работать значительно быстрее при наличии подходящего уникального индекса.
запрос, приведенный SeVa - ошибочен:

1.exists преобразуется к self-join(в терминах команды ms sql),а не к простому Join.Это две большие разницы, выбираются только первые вхождения, а не все.
2.запрос не мой, я его скопировал

автор
Оптимизатор операции на двух и более множествах так или иначе преобразует в join'ы, т.к. других способов объединить множества у него нет (кроме union).

Да, но только для разных наборов могут разные планы выполнения этих join

авторсмысл? join даст join. Это - не неожиданно. А, вот, как
А ты проверь.В ранних версиях MS SQL in и join могли иметь разные планы выполнения, посему in и не рекомендовалось использовать
...
Рейтинг: 0 / 0
04.02.2009, 20:16
    #35797711
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
AAron
какая научная база?

Реляционная алгебра. Которая как раз и
AAron
оперирует множествами

А
AAron
SQL

уже зиждется на реляционной алебре. Которая имеет свои законы, 4 example: rUs=sUr, (rUs)Ut=rU(sUt) и т.п., согласно которым оптимизатор преобразовывает запрос. Вот я и добиваюсь: на основании какого(их) закона(ов) при изЪятии подзапроса из условия в
Код: plaintext
1.
2.
3.
4.
5.
6.
select
     *
from
     TT1 T1
where
     T1.Id=(select T2.TT1_Id from TT2 T2 where T2.Id= 2 )
оптимизатор рожает join.
AAron
например
Код: plaintext
1.
select * from tbl1 where id in (select id from tbl2)
вырождается в обычный inner join. скорее всего он будет полносьтю эквивалентен запросу
Код: plaintext
1.
select tbl1.* from tbl1 inner join tbl2 on tbl2.id = tbl1.id

тынць
Код: plaintext
1.
2.
3.
4.
5.
6.
select
    *
from
    TT1 T1
where
    T1.Id in (select T2.TT1_Id from TT2 T2)
IdVal1TT1_12TT1_2
Код: plaintext
1.
2.
3.
4.
5.
select
    T1.*
from
    TT1 T1
    inner join TT2 T2 on (T2.TT1_Id=T1.Id)
IdVal1TT1_11TT1_11TT1_12TT1_22TT1_22TT1_2

SeVa
MS SQL

У меня его, слава Богу, - нЭт. Я говорю о SQL, а не о каких-то специфических реализациях для определенных серверов определенных версий.
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
04.02.2009, 21:05
    #35797762
AAron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
ок. вариант с джойном может вернуть большее количество записей в случае неуникальности для указанного тынца.
пусть r - фильтруемое множество, s - фильтрующее множество. выполнение операции IN как раз и есть пересечение множеств r и s. а тот символ, который Вы использовали - это объединение множеств, что, согласитесь, несколько иное.
собственно, операции над множествами описаны здесь

насчет того, кто кем оперирует - ваше же утверждение, что SQL базируется на реляционной алгебре, оперирующей множествами, приводит к выводу, что и SQL оперирует множествами.
хотя, согласен, что такая формулировка слишком упрощена, но в данном случае это роли не играет.

законы (именно законы) заставляющие оптимизатор работать так или иначе - это к разработчикам оптимизаторов. Известные мне Oracle и MSSQL в этом случае будут строить джойны (заодно вспомним алгоритмы пересечения множеств). не думаю, что ASE и DB2 сильно отличаются в этом плане.

а вообще, это отношения к теме автора не имеет, варианты емы были предложены. далее - в профильный форум.
закругляюсь.
...
Рейтинг: 0 / 0
04.02.2009, 22:44
    #35797862
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правильно ли писать такие вложеные запросы по выборке
Aron, закон один-стандарт SQL.Прочти его обязательно,тогда ты узнаешь,что "этот символ",как раз и обозначает пересечение.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Правильно ли писать такие вложеные запросы по выборке / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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