2012-01-22 6 views
1

У меня есть следующий sql, который возвращает Проекты и связанные с ними Подрядчики, а также информацию о размере документа из трех разных таблиц. Последовательность: первые Подрядчики вводятся в систему, затем Проекты вводятся для каждого Подрядчика, во время ввода документов (листов). До сих пор так хорошо: Следующий SQL возвращает все проекты вместе с соответствующими подрядчиками и Sheets тонкодисперсными:SQL Server Multitable Выбрать с IF-Else

SELECT 
    dbo.generalcontractors.name, 
    dbo.Projects.*, 
    dbo.sheets.sheetsize, 
    dbo.sheets.sheetid 
FROM 
    dbo.generalcontractors 
INNER JOIN dbo.Projects ON (dbo.generalcontractors.uid = dbo.Projects.generalcontractorid) 
INNER JOIN dbo.sheets ON (dbo.Projects.sheetid = dbo.sheets.sheetid) 
ORDER BY 
    dbo.Projects.projectdate DESC 

Теперь, что должно произойти в том, что документы для отдельных проектов вошли в ProjectDocuments таблицы. У меня есть следующий код, который проверяет наличие документов в таблице ProjectsDocuments и возвращает соответствующие значения; в настоящее время идентификатор проекта жестко закодирован, и он работает.

Вопрос: как я могу объединить следующие sql в sql выше? Я ищу один результат запроса, который отобразит любые соответствующие строки из таблицы ProjectsDocument, и если никакое совпадение не покажет «Не найдено».

Это для SQL Server 2005.

Спасибо!

IF (SELECT COUNT(*) FROM dbo.projectsdocuments, dbo.Projects 
    WHERE projectsdocuments.projectid = Projects.projectid 
    AND Projects.projectid = 5) > 0 
    SELECT * 
    FROM projectsdocuments 
ELSE 
    SELECT 'Not Found' AS HighPrice 
+0

@marc_s. Благодарю. Слишком рано для меня это делать. Любой другой способ я могу вернуть все это в одном запросе? – IrfanClemson

+0

Можете ли вы опубликовать инструкции «СОЗДАТЬ» для таблиц? Таким образом, я могу использовать SSMS для отладки. –

+0

По этому поводу: http://www.mssqltips.com/sqlservertip/1667/sql-server-join-example/ ПРАВИЛЬНЫЙ ВЗГЛЯД РАБОТЫ тоже должен работать. В моем текущем sql это добавлено: «Right OUTER JOIN dbo.projectsdocuments ON (Select * from Projects)», но получение ошибки: «Выражение небулевого типа, указанное в контексте, где ожидается условие, рядом с« ORDER ». '(см. ЗАКАЗ в исходном sql выше). Благодаря! – IrfanClemson

ответ

1

Одним из вариантов было бы просто добавить таблицу ProjectDocuments к вашему запросу, используя LEFT OUTER JOIN.

Если нет соответствующих строк в ProjectDocuments таблице - то все столбцы из этой таблицы будут NULL - так захватив одну из колонн и используя ISNULL(<colname>, 'Not Found') конструкцию, вы бы отображающее «Not Found», когда значения не имеют были найдены в ProjectDocuments:

SELECT 
    gc.name, 
    pr.ProjectDate, pr.Column1, pr.Column2, ....., pr.ColumnN, 
    s.sheetsize, 
    s.sheetid, 
    ISNULL(pd.Name, 'Not Found') AS 'ProjectDocumentName', 
    pd.Column1, ..., pd.ColumnN 
FROM 
    dbo.GeneralContractors gc 
INNER JOIN 
    dbo.Projects pr ON gc.uid = pr.GeneralContractorID 
INNER JOIN 
    dbo.Sheets s ON pr.SheetID = s.SheetID 
LEFT OUTER JOIN 
    dbo.ProjectsDocuments pd ON pr.ProjectID = pd.ProjectID 
ORDER BY 
    pr.ProjectDate DESC 

Две вещи, которые я бы рекомендовал делать:

  • использование значимых псевдонимов таблиц (как gc для GeneralContractor, pr для Project и так далее) - это делает чтение запросы просто тааак гораздо проще ....

  • явно указать столбцы, которые вы хотите, чтобы извлечь из таблиц - что мешает нежелательные сюрпризы, когда ваша таблица имеет пять столбцов BLOB, которые возвращаются, даже если они вам не нужны!

+0

Хорошо, попробуем ваше решение сейчас. Благодаря! – IrfanClemson

+1

Решение, которое работает (за исключением незначительной ошибки: p.ProjectID должен быть pr.projectID - неважно, хотя). Спасибо вам, ребята! – IrfanClemson

+0

Единственная проблема с этим утверждением состоит в том, что он возвращает несколько записей для одного и того же проекта. Например, если есть несколько документов для Проекта - как и ожидалось - я вижу кучу строк с тем же Проектом, но с другим документом. Думаю, мне нужна какая-то «группа» здесь? – IrfanClemson

1

ВЫПОЛНИТЬ ВЗАИМОДЕЙСТВИЕ ProjectDocuments и ВЫБРАТЬ соответствующие поля. Используйте ISNULL, чтобы заменить одно из этих полей на «Не найдено», если нет соответствующих документов.

+0

Я был бы очень признателен, если бы вы могли добавить, что LEFT JOIN в моем первом sql выше ?! Благодарю. – IrfanClemson

+0

Согласно: http: //www.mssqltips.com/sqlservertip/1667/sql-server-join-example/LEFT OUTER JOIN должен работать и автоматически возвращать Nulls, если они не совпадают ?. Но когда я делаю LEFT OUTER JOIN dbo.projectsdocuments ON (dbo.projectsdocument.projectid = dbo.Projects.projectid), я получаю сообщение об ошибке: «Идентификатор многочастности« dbo.projectsdocument.projectid »не может быть связан». – IrfanClemson

+0

Ой! Неправильное имя таблицы. Новый LEFT OUTER JOIN: «LEFT OUTER JOIN dbo.Projects ON (dbo.projectsdocument.projectid = dbo.Projects.projectid) ' Я думаю, что я приближаюсь! – IrfanClemson

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