Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
Здравствуйте! У меня появилась небольшая загвоздка:

есть 2 таблицы Т1 и Т2. как сделать такой запрос, который возвращает всегда количество записей = кол-ву записей Т1, при этом если для записи нет связи с записью T2, то присоединяется (как в запросах с join) null, если есть 1 связь, то она присоединяется, если больше 1, то присоединяется первая запись?
8 июл 09, 09:13    [7389513]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
--__Александр__--
Member

Откуда:
Сообщений: 2631
А что значит первая? Как задано отношения порядка на вашей таблице?
8 июл 09, 09:14    [7389514]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
мне по большому счету неважно какая из записей окажется первой, но пускай таблица Т2 будет упорядочена по первичному ключу (ID)
8 июл 09, 09:18    [7389527]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
alex_yarmolchuk
есть 2 таблицы Т1 и Т2
Если есть, то почему бы не выложить скрипт их создания (CREATE TABLE) с констрейнтами и индексами?
И назвать версию сервера не помешало бы.
И, действительно, что это за "первая запись" такая?
8 июл 09, 09:18    [7389528]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
Прошу прощения, я думал тут не играет роль версия сервера и таблицы.
SQL server 2005

вот таблицы:
CREATE TABLE [dbo].[t1](
	[id] [int] NOT NULL,
 CONSTRAINT [PK_t1] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[t2](
	[id] [int] NOT NULL,
	[id_f] [int] NULL,
 CONSTRAINT [PK_t2] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

вот данные
insert into t1 values (1)
go
insert into t1 values (2)
go

insert into t2 values (1, 1)
go
insert into t2 values (2, 1)
go
insert into t2 values (3, 2)
go

мне нужно выбирать записи из таблицы t1 и t2 таким образом, чтобы не играло роли количество связей с таблицей t2. то есть, если есть связь - хорошо, присоединяем ее, нет - присоединяем нулл, больше одной - присоединяем любую.
8 июл 09, 09:28    [7389543]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
более наглядный пример:

есть таблица с людьми, есть таблица с номерами телефонов. человека может быть произвольное число номеров.

нужно вывести список всех людей, и для каждого человека номер телефона, если номера нет, то пустое значение, если есть хотя бы один номер, то вывести произвольный номер.
8 июл 09, 09:41    [7389581]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
pacha
Member

Откуда:
Сообщений: 239
select id, max(id_f) from
(select t1.id, t2.id_f from t1 left join t2 on (t2.id_f = t1.id)) t
group by t.id 
8 июл 09, 09:51    [7389616]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
pacha
select id, max(id_f) from
(select t1.id, t2.id_f from t1 left join t2 on (t2.id_f = t1.id)) t
group by t.id 


а если у меня, например, в таблице t2 не одно поле, а много id, id_f, attr1, attr2 ... attrN ?

и нужно получить в конечном итоге результат вида:

select t1.*, t2.* (я имею ввиду состав колонок в результирующей таблице)
8 июл 09, 09:59    [7389655]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
такая задача вообще решаема с помощью 1 sql-запроса ?
8 июл 09, 09:59    [7389660]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Так?
SELECT t1.id [t1.id], t2.id[t2.id], t2.id_f[t2.id_f]
FROM t1 OUTER APPLY (SELECT TOP 1 * FROM t2 WHERE t2.id_f=t1.id) t2;
8 июл 09, 10:04    [7389685]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
pacha
Member

Откуда:
Сообщений: 239
по старинке:
select t2.*
from
(
select id, max(id_f) as id_f from
(select t1.id, t2.id_f from t1 left join t2 on (t2.id_f = t1.id)) t
group by t.id 
) t0
join t2 on (t0.id = t2.id and t0.id_f = t2.id_f)
8 июл 09, 10:07    [7389706]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iap
Так?
SELECT t1.id [t1.id], t2.id[t2.id], t2.id_f[t2.id_f]
FROM t1 OUTER APPLY (SELECT TOP 1 * FROM t2 WHERE t2.id_f=t1.id) t2;
Только этот запрос не соответствует теме "помогите составить запрос с join"!
8 июл 09, 10:08    [7389717]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
pacha
Member

Откуда:
Сообщений: 239
в предыдущем моем посте опечатка, вот так:
select t1.*, t2.*
from
(
select t1_id, max(t2_id) as t2_id from
(select t1.id as t1_id, t2.id as t2_id from t1 left join t2 on (t2.id_f = t1.id)) t
group by t1_id 
) t0
join t1 on (t1.id = t0.t1_id)
left join t2 on (t0.t2_id = t2.id)
8 июл 09, 10:18    [7389791]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
iap
iap
Так?
SELECT t1.id [t1.id], t2.id[t2.id], t2.id_f[t2.id_f]
FROM t1 OUTER APPLY (SELECT TOP 1 * FROM t2 WHERE t2.id_f=t1.id) t2;
Только этот запрос не соответствует теме "помогите составить запрос с join"!


да, но вариант отлично работает :)
это стандарт sql или диалект сервера?

pacha

select t2.*
from
(
select id, max(id_f) as id_f from
(select t1.id, t2.id_f from t1 left join t2 on (t2.id_f = t1.id)) t
group by t.id
) t0
join t2 on (t0.id = t2.id and t0.id_f = t2.id_f)

этот запрос возвращает неверное количество записей, и только из одной таблицы (я добавил к исходному примеру два текстовых поля в таблицу t1 и t2 соответственно. внутренний селект возвращает 3 записи внешний - одну.
8 июл 09, 10:22    [7389818]     Ответить | Цитировать Сообщить модератору
 Re: помогите составить запрос с join  [new]
alex_yarmolchuk
Guest
pacha
в предыдущем моем посте опечатка, вот так:
select t1.*, t2.*
from
(
select t1_id, max(t2_id) as t2_id from
(select t1.id as t1_id, t2.id as t2_id from t1 left join t2 on (t2.id_f = t1.id)) t
group by t1_id 
) t0
join t1 on (t1.id = t0.t1_id)
left join t2 on (t0.t2_id = t2.id)


о! теперь работает!!! спасибо!
8 июл 09, 10:23    [7389826]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить