2012-03-18 3 views
0

Я использую базу данных AdvetureWorks. Вот что я хотел бы сделать: Дайте мне фамилию, имя, название компании и перечислите мне все адреса для клиента Вирджиния Миллер, укажите адрес, адрес, город и штат. Вам необходимо объединить 3 таблицы и отфильтровать результаты. Вы должны получить только 2 строки. Это то, что я до сих пор ...Объединение 3 таблиц и фильтрация SQL

Select 
SalesLT.Customer.LastName, 
SalesLT.Customer.FirstName, 
SalesLT.Customer.CompanyName, 
CustomerAddress.AddressType, 
SalesLT.Address.AddressLine1, 
SalesLT.Address.City, 
SalesLT.Address.StateProvince 

From SalesLT.Customer C, SalesLT.CustomerAddress CA, SalesLT.Address A 


join SalesLT.CustomerAddress 

on SalesLT.Address.AddressID=SalesLT.CustomerAddress.AddressID 


join SalesLT.Customer 
on SalesLT.CustomerAddress.CustomerID=SalesLT.Customer.CustomerID 

join SalesLT.Address 
on SalesLT.CustomerAddress.AddressID=SalesLT.Address.AddressID 

Where SalesLT.Customer.FirstName = 'Virginia' 

Да Я новичок и не понимание присоединяется очень хорошо. Любые подталкивания в правильном направлении очень ценятся!

+0

Ваш «От» линии должны иметь только одну таблицу в списке.Строки «join» - это те, которые указывают SQL дополнительные таблицы, из которых вы хотите получить информацию. Так в чем же проблема? Вы объяснили, чего хотите, но не то, что вы пробовали, и какую ошибку или проблему у вас есть. –

+0

Извините, я получаю слишком много строк назад, я должен получить только 2 результата запроса. У меня есть ужасное время с этим, и я пытаюсь понять. –

+0

Запрос выглядит корректно с указанными строками, такими как все, что находится под Select. Я хочу, что так оно и есть? Чтобы показать, что мне нужно в запросе? Это то, где работают соединительные столы? Извините, я очень смущен, но благодарю вас за помощь. –

ответ

1

Точка выбора оператора - это получение некоторых данных определенным образом. Это занимает примерно следующий вид:

select <columns> 
from <table/group of tables joined together/sub-query/tvf etc.> 
where <condition> 

1 - Теперь, немного вы имея проблему с, кажется, средний немного - мы сделаем это первым.

У вас есть три таблицы, которые содержат данные, которые вы хотите вернуться в:

SalesLT.Customer 
SalesLT.CustomerAddress 
SalesLT.Address 

И вы хотите присоединиться к ним вместе на колоннах, где данные относятся друг к другу, в этом случае КодКлиент. Внутреннее соединение оператор принимает следующий вид (выбирая внутреннее соединение, поскольку все записи имеют матч в других таблицах!):

table1 inner join table2 on table1.columnname = table2.columnname 

и если мы сопоставляем ваш пример такого синтаксиса, мы получаем это:

SalesLT.CustomerAddress INNER JOIN 
         SalesLT.Customer ON SalesLT.CustomerAddress.CustomerID = SalesLT.Customer.CustomerID INNER JOIN 
         SalesLT.Address ON SalesLT.CustomerAddress.AddressID = SalesLT.Address.AddressID 

Теперь остальная часть оператора select рассматривает этот запрос как одну большую «коллекцию» данных, почти как если бы это была одна таблица - только каждый столбец предварительно фиксирован именем таблицы. Если вы ссылаетесь на ссылку в другом месте в заявлении, не всегда необходимо включать полное имя (поскольку оно может догадываться, если в результирующем наборе имеется не более одного столбца с тем же именем).

2 - Фильтрация, в которой вы, похоже, имеете место, но вы, кажется, только фильтруете имя, несмотря на ваши первоначальные требования. Добавление дополнительного один легко:

WHERE  (SalesLT.Customer.FirstName = 'Virginia') AND (SalesLT.Customer.LastName = N'Miller') 

3 - Наконец, есть небольшой вопрос, что вы хотите вернуться - это вы уже правильно.

Объединение, что мы сделали вместе, вы получите следующий запрос:

SELECT  SalesLT.Customer.LastName, SalesLT.Customer.FirstName, SalesLT.Customer.CompanyName, SalesLT.CustomerAddress.AddressType, 
         SalesLT.Address.AddressLine1, SalesLT.Address.City, SalesLT.Address.StateProvince 
FROM   SalesLT.CustomerAddress INNER JOIN 
         SalesLT.Customer ON SalesLT.CustomerAddress.CustomerID = SalesLT.Customer.CustomerID INNER JOIN 
         SalesLT.Address ON SalesLT.CustomerAddress.AddressID = SalesLT.Address.AddressID 
WHERE  (SalesLT.Customer.FirstName = 'Virginia') AND (SalesLT.Customer.LastName = N'Miller') 
+0

СПАСИБО ВАС !!!!!! Это показывает, что запрошены две строки! –

+0

Извините, я продолжаю ударять по клавишам, которые посылают, прежде чем я набираю текст! Теперь я оглянусь назад и посмотрю, чего не хватает. Обнимаю вас и всех за потрясающую помощь !!! –

+0

Я думал, что объяснение вместе с ответом поможет вам лучше понять его! – Bridge

0

У меня нет установленной приключенческой БД, поэтому я не знаю отношений. Если предположить, что отношения упомянутых вами справедливы, это должно работать:

USE SalesLT 

SELECT 
c.LastName, 
c.FirstName, 
c.CompanyName, 
ca.AddressType, 
a.AddressLine1, 
a.City, 
a.StateProvince, 
FROM Customer C 
INNER JOIN CustomerAddress ca ON ca.CustomerID = c.CustomerID 
LEFT JOIN Address a ON a.AddressID = ca.AddressID 
WHERE c.FirstName = 'Virginia' 

Notes - Я LEFT JOIN на адрес, потому что я не знаю, есть ли может быть запись клиента, без адреса записи. В случаях, когда это возможно, и вы по-прежнему хотите включать записи для клиентов даже без адресов, используйте LEFT JOIN и COALESCE для идентификационных записей NULL.

+0

О, мой! Спасибо, я попробую это. Я так новичок, это очень запутанно, но я практикую! –

+0

К сожалению, это вернулось со многими красными линиями и ошибкой. Я не знаю, что такое COALESCE. –

+0

COALESCE - это заявление с высокой степенью использования. Он просто принимает первое значение, отличное от NULL, поэтому COALESCE (a.AddressLine1, a.AddressLine2, c.SomeOtherField, «Все эти поля являются NULL») будет принимать первое ненулевое значение или вывод. Все эти поля имеют значение NULL. Вы можете взять COALESCE, если хотите, я обычно бросаю их туда для LEFT JOINS, чтобы я мог диктовать то, что возвращается в случае значения поля NULL. –

1

Я считаю, что следующее должно исправить вашу проблему.

USE SalesLT 

SELECT 
    c.LastName, 
    c.FirstName, 
    c.CompanyName, 
    ca.AddressType, 
    a.AddressLine1, 
    a.City, 
    a.StateProvince 

FROM 
    Customer c 

JOIN 
    CustomerAddress ca 
    ON c.CustomerID=ca.CustomerID 

JOIN 
    Address a 
    ON ca.AddressID=a.AddressID 

WHERE 
    c.FirstName = 'Virginia' 
    AND c.LastName = 'Miller' 

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

USE SalesLT 

SELECT 
    c.LastName, 
    c.FirstName 

FROM 
    Customer c 

WHERE 
    c.FirstName = 'Virginia' 
    AND c.LastName = 'Miller' 

Так что вы сделали там запускается указано, какие базы данных вы собираетесь использовать (это SalesLT линия USE). Это поможет с типизацией, поэтому вам не нужно добавлять ее перед каждым именем таблицы.

Далее вы выбираете имена столбцов, которые вас интересуют (LastName и FirstName). У них есть "c." перед ними, чтобы указать псевдоним или «псевдоним» таблицы, мы говорим, что SQL может найти эти данные.

В строке «FROM» вы можете видеть, что вы говорите SQL, чтобы посмотреть в Customer table и что вы собираетесь присвоить этой таблице псевдоним «c», чтобы вы могли быстро ссылаться на него и разъяснять, какие столбцы принадлежат к какому из таблиц в вашем запросе.

Теперь, когда вы возвращаете данные для Вирджинии Миллер, вы можете посмотреть следующий фрагмент. Вам нужен адрес для Вирджинии, поэтому вам потребуется какой-то способ связать адресные данные с данными клиента.

К счастью, база данных AdventureWorks делает это довольно легко, потому что у них есть таблица «join» CustomerAddress. Подобная таблица предназначена для простых записей ссылок между двумя таблицами с некоторыми типами столбцов идентификаторов. В этом случае он связывает CustomerID (который является столбцом в таблице Customer) и AddressID (который является столбцом в таблице Address), чтобы мы могли выяснить адреса, которые могут иметь определенные клиенты.

Итак, теперь мы знаем, что нам понадобятся данные от CustomerAddress, поэтому мы должны добавить эту следующую часть в наш запрос.

USE SalesLT 

SELECT 
    c.LastName, 
    c.FirstName, 
    c.CompanyName, 
    ca.AddressType 

FROM 
    Customer c 

JOIN 
    CustomerAddress ca 
    ON c.CustomerID=ca.CustomerID 

WHERE 
     c.FirstName = 'Virginia' 
     AND c.LastName = 'Miller' 

Новые части в приведенном выше коде являются добавление выбора AddressType из таблицы CustomerAddress, а затем говорить SQL, как связаны таблицы клиентов и таблицы CustomerAddress. Он может связывать записи между ними, потому что CustomerID в таблице Customer равен идентификатору клиента в таблице CustomerAddress (JOIN CustomerAddress ca ON c.CustomerID = ca.CustomerID). «Ca» - это ник или псевдоним, который мы предоставили таблице CustomerAddress, чтобы вы использовали это, чтобы ссылаться на него везде в запросе.

Теперь, когда у нас есть эта часть запроса, мы готовы к заключительному этапу получения фактической адресной информации.

USE SalesLT 

SELECT 
    c.LastName, 
    c.FirstName, 
    c.CompanyName, 
    ca.AddressType 

FROM 
    Customer c 

JOIN 
    CustomerAddress ca 
    ON c.CustomerID = ca.CustomerID 

JOIN 
    Address a 
    ON a.AddressID = ca.AddressID 

WHERE 
     c.FirstName = 'Virginia' 
     AND c.LastName = 'Miller' 

Этот последний шаг просто добавил дополнительную информацию о том, как таблица адресов связана с таблицей CustomerAddress. В основном столбец AddressID в CustomerAddress равен столбцу AddressID в адресе.

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

Решение проблемы шаг за шагом обычно является хорошим способом.

+0

Спасибо, я попробую и вернусь. Это великолепный сайт. –

+0

У всех есть красная линия под ним, и я получаю эту ошибку ... –

+0

Msg 208, Level 16, State 1, Line 1 Неверное имя объекта «Клиент». –

Смежные вопросы