2013-04-26 2 views
0

У меня есть стол для сообщений, в котором есть подкатегория фотографий, поэтому у одного сообщения может быть много фотографий, один из столбцов таблицы фотографий - [Приоритет].SQL Server + Выбор записей с элементами подставок

мне нужно выбрать записи из почтовой таблицы только с фото, который имеет наивысший приоритет в другой таблице:

Так что результат должен быть как:

Photo Post 
pic1 Article1 
picX Article2 

В настоящее время мои результаты показывают, как

Photo Post 
pic1 Article1 
pic2 Article1 
picX Article2 

с этим запросом:

SELECT [Photo], 
     [PostTitle] 
FROM [Post] sp 
INNER JOIN [PostPhotos] spp 
ON (sp.AutoId = spp.PostId) 
WHERE sp.[AutoId] IN (SELECT [PostID] 
         FROM [Favorites] 
         WHERE [UserId] = 'UserXXX') 

Я попробовал присоединиться запрос без успеха:

SELECT photo, 
     [PostTitle], 
     [AskingPrice] 
FROM (SELECT sp.[AutoId], 
       [PostTitle] 
     FROM [SellPost] sp 
     WHERE sp.[AutoId] IN (SELECT [PostID] 
          FROM [Favorites] 
          WHERE [UserId] = 'UserId'))a 
full OUTER JOIN(SELECT TOP 1 [PostId], 
         [photo] 
       FROM [PostPhotos] spp 
       WHERE PostId IN (SELECT [PostID] 
            FROM [Favorites] 
            WHERE [UserId] = 'UserXXX') 
       ORDER BY [Priority] ASC)b 
    on (a.AutoId = b.PostId) 
    order by a.AutoId; 

Мои таблицы:

Table Post 
PostId, PostTitle 

Table PostPhotos 
AutoId, PostId, Photo, Priority --> 1 post can have many photos 

Может кто-то пожалуйста, любезно помочь. Благодарю.

ответ

0

Извините за ошибки в моем посте, я думаю, что я думал слишком глубоко, все, что мне нужно было:

SELECT [p].[AutoId], [PostTitle], [Photo] FROM [Post] p 
     INNER JOIN [PostPhotos] pp 
     ON [p].[AutoId] = [pp].[PostId] 
     WHERE p.[AutoId] IN (SELECT [PostID] FROM [Favorites] WHERE [UserId] = @UserId) 
     AND [Priority] = 1 
0

Попробуйте с этим намеком:

SELECT [p].[PostId],[PostTitle],[Photo] FROM [Post] p 
INNER JOIN [PostPhots] pp 
ON [p].[PostId] = [pp].[PostId] 
WHERE [p].[PostId] 
IN (SELECT TOP 1 [PostId] FROM [PostPhotos] ORDER BY [Priority] DESC) 
0

Несколько вещей не ясны из вашего описания (например, что AutoId, что является первичным ключом PostPhotos и то, что вы делаете с Favorites/что делает эту таблицу вид как). Но вот общая идея:

WITH RankedPhotos AS (
    SELECT 
    PostId, 
    AutoId, -- I'm assuming this is the primary key of PostPhotos? 
    RANK() OVER (PARTITION BY AutoId, PostId ORDER BY Priority ASC) AS PhotoRank 
    FROM 
    Post p JOIN 
    PostPhotos pp ON 
     p.PostId = pp.PostId 
), TopPhotos AS (
    SELECT 
    PostId, 
    AutoId 
    FROM 
    RankedPhotos 
    WHERE 
    PhotoRank = 1 
) 
SELECT 
    PostTitle, 
    Photo 
FROM 
    RankedPhotos r JOIN 
    Post p ON 
    r.PostId = p.PostId JOIN 
    PostPhotos pp ON 
    r.AutoId = p.AutoId 

Конечно, вы могли бы разворачивать КТР и использовать вложенные подзапросы (вы можете также, вероятно, избавиться от TopPhotos полностью), но это, вероятно, легче увидеть/понять.

Основная идея:

  • В RankedPhotos, «Оценка» все Post/PostPhoto пара
  • В TopPhotos фильтре идентификаторов до тех с самыми высокими рангами
  • Присоединяйтесь назад оригинальные таблицы, чтобы получить нужные вам записи

Очевидно, что если вам нужно отфильтровать по другим критериям (например, пользователь), которые необходимо будет добавить. Лучше всего добавить, что как можно раньше (т. Е. В RankedPhotos), поскольку в противном случае база данных может в конечном итоге выполнять больше работы, чем она требуется.

0

подзапросы не мой конек, но я думаю, что ниже может работать:

SELECT t1.Photo, t2.PostTitle 
FROM Post t2 
    INNER JOIN PostPhotos t1 ON (t2.PostID = t1.PostID) 
WHERE t1.AutoID IN (SELECT TOP 1 d.AutoID, d.PostID 
         FROM PostPhotos As d 
         WHERE d.PostID = t1.PostID 
         ORDER BY d.Priority, d.AutoID) 

Примечание добавление d.AutoID в упорядочении подзапроса, это в случае, если две фотографии имеют одинаковый приоритет.

EDIT я узнал много того, что я знаю о подзапросов here

0
SELECT B.Photo,A.[PostTitle] 
FROM [Post] A INNER JOIN 
     (SELECT AutoId,PostId,Photo,Priority 
     FROM PostPhotos 
     WHERE Priority =1) B ON A.[PostId] = B.[PostId] 

Я бы сделал это таким образом, и оба внутренних соединения и левого соединения могут получить желаемый результат.

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