Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
Есть 2 таблицы со связью 1:N. Задача выбрать одним запросом все поля из 1 и 2 таблицы, взяв из 2-ой одну запись с максимальным/минимальным/средним(утрирую) номером. Пример: tab1 id name 1 ddd 2 dff 3 ggh tab2 id_tab1 id data 1 1 '2002.1.1' 1 2 '2002.1.3' 2 10 '2002.3.1' 2 11 '2002.3.2' Результат: tab1.id tab1.name tab2.id_tab1 tab2.id tab2.data 1 ddd 1 1 '2002.1.1' 2 dff 2 10 '2002.3.1' 3 ggh null null null ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2002, 12:47 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
select t1.*, t2.* from (select t1.*, (select top 1 id from table2 t2 where t2.id_tab1 = t1.id order by t2.date desc) AS t2_id from table1 t1 ) AS t1 left outer join table2 t2 on t2.id = t1.t2_id ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2002, 13:41 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Glory, All Хочу услышать критику другого варианта, при условии, что значения tab2.data уникальны в пределах tab2.id_tab1 set nocount on create table #tab1 (id int, name varchar(3)) insert #tab1 (id, name) select 1, 'ddd' insert #tab1 (id, name) select 2, 'dff' insert #tab1 (id, name) select 3, 'ggh' create table #tab2 (id_tab1 int, id int, data int) insert #tab2 (id_tab1, id, data) select 1, 1, 20020101 insert #tab2 (id_tab1, id, data) select 1, 2, 20020103 insert #tab2 (id_tab1, id, data) select 2, 10, 20020301 insert #tab2 (id_tab1, id, data) select 2, 11, 20020302 select t1.id, t1.name, t2.id_tab1, t2.id, t2.data from (select id_tab1, min(data) as min_data from #tab2 group by id_tab1) as t inner join #tab2 as t2 on t2.id_tab1 = t.id_tab1 and t2.data = t.min_data right outer join #tab1 as t1 on t1.id = t2.id_tab1 /* Вариант Glory select t1.id, t1.name, t2.id_tab1, t2.id, t2.data from (select t1.*, (select top 1 id from #tab2 t2 where t2.id_tab1 = t1.id order by t2.data asc) AS t2_id from #tab1 t1 ) AS t1 left outer join #tab2 t2 on t2.id = t1.t2_id */ drop table #tab1 drop table #tab2 set nocount off P.S. Понятнее, проще и удобнее в прочтении и написании критикой не признается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 08:55 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
IMHO - для уникальных значений tab2.data в пределах tab2.id_tab1 ваш запрос лучше - а вот для неуникальных, запрос не выполнит ваше же условие "взяв из 2-ой одну запись" Так что - каждому свое. ЗЫ В начальном сообщении вы не сказали ничего насчет уникальности/неуникальности, поэтому я и предложил более общий пример. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 09:24 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
Ребят, а если id составной(а не одним полем)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 09:58 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Snake Если уникальность присутствует, подойдет и мой вариант. Добавьте ключ в qroup by и условия соединения. Если нет, то можно, например, через временную таблицу с identity_id, заполненную в нужном вам порядке. А из нее уже по min|max|(identity_id). Критика принимается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 10:21 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
Интересно, а часто ли в БД (по "уму" спроектированных) приходится переходить от связи 1:N к 1:1 или мне пересмотреть структуру? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 10:37 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Glory И, все таки, сомнения остаются. Может быть прокомментируете. Стоит добавить primary key. alter table #tab1 add constraint pk1 primary key(id) alter table #tab2 add constraint pk2 primary key(id) и Ваш запрос становится шустрее. Не спасает даже индексирование. create index idx on #tab2(id_tab1) create index idx2 on #tab2(data) Надо будет посмотреть на больших объемах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 13:32 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Glory Не раз наверное слышали спасибо в свой адрес? Очередное ... 2 Michael+Hopgarden Решений действительно несколько. Из всех нами придуманных решение Glory эффективнее (проверено и набольших обьемах) да просто достатоно взглянуть на план. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 14:57 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Michael+Hopgarden Да, действительно при clustered primary key из плана "моего" запроса пропадает один Hash Join. А во втором запросе всегда остается шаг Table Spool/Lazy Spool, что мне лично не нравится. Это первое. Второе, из того же плана выполнения видно каждый шаг "моего" запроса дает меньше(или не больше) записей на выходе, чем у запроса Snake. Хотя странно, что при совместном выполнении, QA показывает незначительное преимущество запроса от Snake. 48% vs 52%. Без primary key перекос еще больше 41 vs 59 2Snake Если не секрет, на каких конкретно больших объемах вы проверяли запросы ? И за спасибо - спасибо . Доброе слово оно, как говорится, и кошке приятно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2002, 15:28 |
|
||
|
Сложный select
|
|||
|---|---|---|---|
|
#18+
2 Glory Проверял на 2 таблицах: 1 - 40 полей (в основном char не больше 10 байт) 2 - 83 поля (6 - полей text, остальные char не больше 10 байт и несколько целых) В обоих таблицах первичный ключ по полю int (IDENTITY) кластерный, но связка проходит по нескольки полям, по которым построен уникальный индекс. В левой таблице 107955 записей. И соответственно результат за 1 мин. 28 сек. (123 поля, 107955 записей) PS win2k as sp1, sql2k sp2,2-P3 - 700Mh,RAID5,1Gb RAM PPS Сообственно вот сам запрос: select t1.*, t2.* from (select t1.*, (select top 1 nidn from reestr t2 where t2.filial = t1.filial and t2.kniga = t1.kniga and t2.god_kn = t1.god_kn and t2.nomerkn = t1.nomerkn and t2.nomerreg = t1.nomerreg order by t2.nidn asc) AS t2_nidn from status t1 ) AS t1 left outer join reestr t2 on t2.filial = t1.filial and t2.kniga = t1.kniga and t2.god_kn = t1.god_kn and t2.nomerkn = t1.nomerkn and t2.nomerreg= t1.nomerreg and t2.nidn = t1.t2_nidn ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2002, 04:47 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32027761&tid=1823111]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
89ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
2ms |
| others: | 264ms |
| total: | 461ms |

| 0 / 0 |
