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

Откуда:
Сообщений: 355
Уважаемые форумчане!

Надеюсь Вы мне поможете. Хочу написать запрос из 3х таблиц.
1-я таблица: Customer (KOD_Customer, NAME_Customer) только ФИО клиентов
2-я таблица: Adress (KOD_Customer, INN, ADRESS, PHONE и т.д) адреса клиентов
3-я таблица: PASSPORT (KOD_Customer, PASSPORT_PP, PASSPORT_NOMER, PASSPORT_SERIA, PASSPORT_DATA_BEGIN, PASSPORT_DATA_END) периодические паспортные данные клиентов

Необходимо получить следующее из 3х таблиц:

KOD_Customer, NAME_Customer, INN, ADRESS, PHONE, PASSPORT_NOMER, PASSPORT_SERIA, PASSPORT_DATA_BEGIN, PASSPORT_DATA_END

т.е. если у клиента в 3-ей таблице несколько паспортных данных, тогда мы должны вытащить список клиентов только с последним паспортом...

Заранее благодарен.
5 июл 13, 10:26    [14525893]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Александр52
Member

Откуда: Кокосовые острова ส็็็็็
Сообщений: 5136
ularsoft, используйте JOIN.
Определите для начала что будет из себя представлять каждая запись в таблице, а дальше выводите её свойства.
5 июл 13, 10:28    [14525903]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Glory
Member

Откуда:
Сообщений: 104751
ularsoft
Необходимо получить следующее из 3х таблиц:

KOD_Customer, NAME_Customer, INN, ADRESS, PHONE, PASSPORT_NOMER, PASSPORT_SERIA, PASSPORT_DATA_BEGIN, PASSPORT_DATA_END

т.е. если у клиента в 3-ей таблице несколько паспортных данных, тогда мы должны вытащить список клиентов только с последним паспортом...

В какой части задачи возникли проблемы ? Какой запрос вы попробовали написать ?
5 июл 13, 10:30    [14525910]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
ularsoft,

что-то не видно Вашего варианта решения задачи.
Где версия сервера, CREATE TABLE, INSERT тестовых данных и т.д.?
5 июл 13, 10:30    [14525914]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Добрый Э - Эх
Guest
ularsoft
т.е. если у клиента в 3-ей таблице несколько паспортных данных, тогда мы должны вытащить список клиентов только с последним паспортом...

трижды порванный баян

Остальное - банальный [LEFT] JOIN
5 июл 13, 11:08    [14526174]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
СУБД MS SQL. Есть БД. В ней таблицы Customer, Adress, PASSPORT. Делаю вот такой запрос:

SELECT * FROM PASSPORT RIGHT OUTER JOIN Customer INNER JOIN Adress ON Customer.KOD_Customer = Adress.KOD_Customer ON PASSPORT.KOD_Customer = Customer.KOD_Customer
5 июл 13, 11:15    [14526242]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Добрый Э - Эх
Guest
ularsoft
СУБД MS SQL.
Их, если что, сильно больше одного. Какой из них у тебя? Или
select @@version
у тебя под запретом?
5 июл 13, 11:17    [14526258]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
2000
5 июл 13, 11:18    [14526264]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
ularsoft
2000

это у вас так select @@version отработала?:)
5 июл 13, 11:19    [14526275]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 612
а если во второй таблице несколько адресов или телефонов? если толко один, то можно так

SELECT
	c.[KOD_Customer]
	,c.[NAME_Customer]
	,a.[INN]
	,a.[ADRESS]
	,a.[PHONE]
	,p.[PASSPORT_PP]
	,p.[PASSPORT_NOMER]
	,p.[PASSPORT_SERIA]
	,p.[PASSPORT_DATA_BEGIN]
	,p.[PASSPORT_DATA_END]
FROM Customer c
JOIN Adress a ON c.[KOD_Customer] = a.[KOD_Customer]
JOIN (
		SELECT 
			p.[KOD_Customer]
			,p.[PASSPORT_PP]
			,p.[PASSPORT_NOMER]
			,p.[PASSPORT_SERIA]
			,p.[PASSPORT_DATA_BEGIN]
			,p.[PASSPORT_DATA_END] 
		FROM PASSPORT p 
		JOIN (SELECT r.[KOD_Customer], MAX(r.[PASSPORT_DATA_BEGIN]) AS [MAX_PASSPORT_DATA_BEGIN] FROM PASSPORT r) AS r 
		ON p.[KOD_Customer] = r.[KOD_Customer] AND p.[PASSPORT_DATA_BEGIN] = r.[MAX_PASSPORT_DATA_BEGIN]
	) AS p ON p.[KOD_Customer] = c.[KOD_Customer]

т.е. последний паспорт выбирается для каждого клиента по максимальной дате начала.
если таблицы большие, то не помешают неуникальные индесы на таблицы 2 и 3 на поле [KOD_Customer], причем для 3 в индекс можно включить [PASSPORT_DATA_BEGIN].
5 июл 13, 11:19    [14526276]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Добрый Э - Эх
Guest
Ещё раз...

Чтобы разобраться вот с этим:
ularsoft
если у клиента в 3-ей таблице несколько паспортных данных, тогда мы должны вытащить список клиентов только с последним паспортом...


нужно осмысленно почитать вот тут: трижды порванный баян

Остальное - банальные JOIN-ы, до которых ты и сам додумался.
5 июл 13, 11:19    [14526279]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
ularsoft,

ИНН в адресе — это, блин, оригинально ...
5 июл 13, 11:21    [14526298]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
ularsoft,

Date_begin = (select max( date_begin ) from passport p1 where p1.
5 июл 13, 11:25    [14526327]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
н-р, у клиента несколько паспортов:
1. XX 11111 10.04.1993
2. YY 22222 15.04.2003
3. ZZ 33333 30.04.2013
и как получить список клиентов только с последним паспортом??? т.е. вот так:

код клиента: 555
ФИО: Иванов П.А.
адрес: г.Москва
тел: 111-111-111-111
...
номер паспорта: ZZ
серия паспорта: 33333
дата выдачи паспорта: 30.04.2013
5 июл 13, 11:25    [14526329]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
ularsoft,

Date_begin = (select max( date_begin ) from passport p1 where p1. KOD_Customer = cust. KOD_Customer )


Остальное — просто join ы.


Если такое для тебя сложно, видимо, ты не тем занимаешься.
5 июл 13, 11:27    [14526358]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
какая разница чем я занимаюсь, просто прошу помощи
5 июл 13, 11:30    [14526387]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Добрый Э - Эх
Guest
ularsoft
н-р, у клиента несколько паспортов:
1. XX 11111 10.04.1993
2. YY 22222 15.04.2003
3. ZZ 33333 30.04.2013
и как получить список клиентов только с последним паспортом??? т.е. вот так:
Чукча ниразу не читатель?
Я тебе на решение этого момента два разу ссылку давал...

Даю третий раз: трижды порванный баян
5 июл 13, 11:31    [14526395]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1887
Дык раз боян трижды порванный то и ссылаться на него надо 3 раза
5 июл 13, 11:35    [14526437]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Добрый Э - Эх
Даю третий раз: трижды порванный баян
В той простой задаче про паспорт ни слова не сказано!
5 июл 13, 11:43    [14526520]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
Диклевич Александр
а если во второй таблице несколько адресов или телефонов? если толко один, то можно так

SELECT
	c.[KOD_Customer]
	,c.[NAME_Customer]
	,a.[INN]
	,a.[ADRESS]
	,a.[PHONE]
	,p.[PASSPORT_PP]
	,p.[PASSPORT_NOMER]
	,p.[PASSPORT_SERIA]
	,p.[PASSPORT_DATA_BEGIN]
	,p.[PASSPORT_DATA_END]
FROM Customer c
JOIN Adress a ON c.[KOD_Customer] = a.[KOD_Customer]
JOIN (
		SELECT 
			p.[KOD_Customer]
			,p.[PASSPORT_PP]
			,p.[PASSPORT_NOMER]
			,p.[PASSPORT_SERIA]
			,p.[PASSPORT_DATA_BEGIN]
			,p.[PASSPORT_DATA_END] 
		FROM PASSPORT p 
		JOIN (SELECT r.[KOD_Customer], MAX(r.[PASSPORT_DATA_BEGIN]) AS [MAX_PASSPORT_DATA_BEGIN] FROM PASSPORT r) AS r 
		ON p.[KOD_Customer] = r.[KOD_Customer] AND p.[PASSPORT_DATA_BEGIN] = r.[MAX_PASSPORT_DATA_BEGIN]
	) AS p ON p.[KOD_Customer] = c.[KOD_Customer]

т.е. последний паспорт выбирается для каждого клиента по максимальной дате начала.
если таблицы большие, то не помешают неуникальные индесы на таблицы 2 и 3 на поле [KOD_Customer], причем для 3 в индекс можно включить [PASSPORT_DATA_BEGIN].


Точно Вы были правы, у меня во 2 табл. несколько адресов, как быть?
5 июл 13, 13:48    [14527489]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Glory
Member

Откуда:
Сообщений: 104751
ularsoft
Точно Вы были правы, у меня во 2 табл. несколько адресов, как быть?

Точно так же, как с нескоолькими паспортами - выбрать один
5 июл 13, 13:50    [14527509]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
i'm a guest here
Guest
ularsoft,

USE tempdb
GO

IF EXISTS(SELECT * FROM sysobjects o WHERE o.name LIKE '#customer%')
DROP TABLE #customer
GO

IF EXISTS(SELECT * FROM sysobjects o WHERE o.name LIKE '#passport%')
DROP TABLE #passport
GO

CREATE TABLE #customer(
	KOD_Customer INT, 
	NAME_Customer VARCHAR(50))
	
INSERT INTO #customer VALUES (1, 'some customer')

CREATE TABLE #passport(
	KOD_Customer INT, 
	PASSPORT_SERIA CHAR(4), 
	PASSPORT_NOMER CHAR(6), 
	PASSPORT_DATA_BEGIN DATETIME) 

INSERT INTO #passport VALUES (1, '1111', '111111', '20010101')
INSERT INTO #passport VALUES (1, '1111', '111112', '20010102')

SELECT
	c.*,
	p.*
FROM
	#customer AS c
LEFT JOIN
	#passport AS p
INNER JOIN
(
SELECT
	p.KOD_Customer,
	PASSPORT_DATA_BEGIN = MAX(p.PASSPORT_DATA_BEGIN)
FROM	
	#passport AS p
GROUP BY
	p.KOD_Customer
) AS cur_p
ON
	p.PASSPORT_DATA_BEGIN = cur_p.PASSPORT_DATA_BEGIN
ON
	c.KOD_Customer = p.KOD_Customer 
5 июл 13, 14:36    [14527818]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
i'm a guest here
Guest
i'm a guest here,

упс проглядел подобный ответ выше от Диклевич Александр.
5 июл 13, 14:39    [14527850]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 612
ularsoft,

выбрать последний, по аналогии с паспортами.
я не знаю, есть ли там признаки типа даты адреса.
5 июл 13, 15:18    [14528185]     Ответить | Цитировать Сообщить модератору
 Re: Тяжелый запрос для меня  [new]
ularsoft
Member

Откуда:
Сообщений: 355
Ребята, всем огромное спасибо за содействия!!! У меня все получилось. Работает отлично, в душе спокойно. Особая благодарность Диклевичу Александру!!!
16 июл 13, 13:07    [14572742]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить