2015-03-29 3 views
0

Я пытаюсь объединить три таблицы, чтобы отбросить список отдельных сообщений в блогах с соответствующими активами (изображения и т. Д.), Но я продолжаю подниматься на обрезку. Три таблетки: tblBlog, tblAssetLink и tblAssets. Планшет Blog держит блог, таблица активов содержит активы, а таблица Assetlink связывает их вместе.Как присоединиться к трем таблицам с отличными

tblBlog.BID является PK в блоге, tblAssets.AID является ПК в активах.

Этот запрос работает, но отбрасывает несколько сообщений для одной записи. Я попытался использовать select distinct и group by and even union, но поскольку мои знания довольно слабы с SQL - они все ошибки.

Я также хотел бы учесть любые активы, помеченные как удаленные (tblAssets.Deleted = true), но не скрывать связанное сообщение в блоге (если это не отмечено как удаленное). Если кто-то может помочь - он будет очень признателен! Благодарю.

Вот мой запрос до сих пор ....

SELECT dbo.tblBlog.BID, 
     dbo.tblBlog.DateAdded, 
     dbo.tblBlog.PMonthName, 
     dbo.tblBlog.PDay, 
     dbo.tblBlog.Header, 
     dbo.tblBlog.AddedBy, 
     dbo.tblBlog.PContent, 
     dbo.tblBlog.Category, 
     dbo.tblBlog.Deleted, 
     dbo.tblBlog.Intro, 
     dbo.tblBlog.Tags, 
     dbo.tblAssets.Name, 
     dbo.tblAssets.Description, 
     dbo.tblAssets.Location, 
     dbo.tblAssets.Deleted AS Expr1, 
     dbo.tblAssetLink.Priority 
FROM dbo.tblBlog 
     LEFT OUTER JOIN dbo.tblAssetLink 
     ON dbo.tblBlog.BID = dbo.tblAssetLink.BID 
     LEFT OUTER JOIN dbo.tblAssets 
     ON dbo.tblAssetLink.AID = dbo.tblAssets.AID 
WHERE (dbo.tblBlog.Deleted = 'False') 

ORDER BY dbo.tblAssetLink.Priority, tblBlog.DateAdded DESC 

EDIT

Изменена Where и order by ....

Ожидаемый результат:

tblBlog.BID = 123 

tblBlog.DateAdded = 12/04/2015 

tblBlog.Header = This is a header 

tblBlog.AddedBy = Persons name 

tblBlog.PContent = *text* 

tblBlog.Category = Category name 

tblBlog.Deleted = False 

tblBlog.Intro = *text* 

tblBlog.Tags = Tag, Tag, Tag 

tblAssets.Name = some.jpg 

tblAssets.Description = Asset desc 

tblAssets.Location = Location name 

tblAssets.Priority = True 
+0

Пожалуйста, добавьте данные примера и ожидаемые результаты –

+0

Пожалуйста ** не ** поместить образцы кода или достаточно данных в комментариях - так как вы не можете отформатировать его, это чрезвычайно сложно ** прочитать его ... Вместо этого: ** обновите ** свой вопрос, отредактировав его, чтобы предоставить дополнительную информацию! Спасибо. –

+0

извините, я просто заметил это и обновил выше –

ответ

0

Использование OUTER APPLY:

DECLARE @b TABLE (BID INT) 
DECLARE @a TABLE (AID INT) 
DECLARE @ba TABLE 
    (
     BID INT , 
     AID INT , 
     Priority INT 
    ) 

INSERT INTO @b 
VALUES (1), 
     (2) 

INSERT INTO @a 
VALUES (1), 
     (2), 
     (3), 
     (4) 

INSERT INTO @ba 
VALUES (1, 1, 1), 
     (1, 2, 2), 
     (2, 1, 1), 
     (2, 2, 2) 


SELECT * 
FROM @b b 
     OUTER APPLY (SELECT TOP 1 
           a.* 
         FROM  @ba ba 
           JOIN @a a ON a.AID = ba.AID 
         WHERE  ba.BID = b.BID 
         ORDER BY Priority 
        ) o 

Выход:

BID AID 
1 1 
2 1 

Что-то вроде:

SELECT b.BID , 
     b.DateAdded , 
     b.PMonthName , 
     b.PDay , 
     b.Header , 
     b.AddedBy , 
     b.PContent , 
     b.Category , 
     b.Deleted , 
     b.Intro , 
     b.Tags , 
     o.Name , 
     o.Description , 
     o.Location , 
     o.Deleted AS Expr1 , 
     o.Priority 
FROM dbo.tblBlog b 
     OUTER APPLY (SELECT TOP 1 
           a.* , 
           al.Priority 
         FROM  dbo.tblAssetLink al 
           JOIN dbo.tblAssets a ON al.AID = a.AID 
         WHERE  b.BID = al.BID 
         ORDER BY al.Priority 
        ) o 
WHERE b.Deleted = 'False' 
+0

Спасибо! Это исправило мою проблему :) –

0

Вы не можете j в трех таблицах, если они не имеют одинаковый атрибут. Он будет работать, если все таблицы имеют BID, но второе соединение пытается присоединиться к AID. Какой из них не будет работать. Все они должны иметь BID.

+0

AID и BID оба находятся в AssetLink - это таблица, которая объединяет их вместе –

0

на основе ваших комментариев

я хотел бы получить только один актив в блоге (верхний заказанный по приоритету)

Вы можете изменить свой запрос следующим образом. Я предлагаю изменить соединение с dbo.tblAssetLink на отфильтрованное, содержащее только одну ссылку (самый высокий приоритет) для каждого блога.

SELECT dbo.tblBlog.BID, 
     dbo.tblBlog.DateAdded, 
     dbo.tblBlog.PMonthName, 
     dbo.tblBlog.PDay, 
     dbo.tblBlog.Header, 
     dbo.tblBlog.AddedBy, 
     dbo.tblBlog.PContent, 
     dbo.tblBlog.Category, 
     dbo.tblBlog.Deleted, 
     dbo.tblBlog.Intro, 
     dbo.tblBlog.Tags, 
     dbo.tblAssets.Name, 
     dbo.tblAssets.Description, 
     dbo.tblAssets.Location, 
     dbo.tblAssets.Deleted AS Expr1, 
     dbo.tblAssetLink.Priority 
FROM dbo.tblBlog 
     LEFT OUTER JOIN 
     (SELECT BID, AID, 
     ROW_NUMBER() OVER (PARTITION BY BID ORDER BY [Priority] DESC) as N 
     FROM dbo.tblAssetLink) AS filteredAssetLink 
     ON dbo.tblBlog.BID = filteredAssetLink.BID 
     LEFT OUTER JOIN dbo.tblAssets 
     ON filteredAssetLink.AID = dbo.tblAssets.AID 
WHERE dbo.tblBlog.Deleted = 'False' AND filteredAssetLink.N = 1 
ORDER BY tblBlog.DateAdded DESC 
+0

Спасибо! Я уверен, что это сработает хорошо, но я добрался до @Giorgi Nakeuri, поэтому я использовал его решение. –

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