加入另一个表中的唯一ID

时间:2013-05-07 11:02:16

标签: sql tsql join paging

以下是故事:我必须实现过滤器。在此过滤器中,我会过滤某些类别。 其中一个过滤器是“最喜欢的”过滤器(@includeFavourites)。

我有这个庞大的SQL,有分页和排序等等。

现在,当点击过滤器中的“includeFavourites”选项时,我还必须从不同的表中选择唯一的ID(这些条目存储在不同的数据表中),其中存储了收藏夹。 我尝试过左外连接,但它返回主表中每条记录的“收藏数”记录。 Coalesce根本没有帮助。

这是我的SQL:

            --this is needed because stored procedure must know how many days are selected
            DECLARE @daysCount int
            SET @daysCount = 0
            IF (@mon IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@tue IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@wed IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@thu IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@fri IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@sat IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END
            IF (@sun IS NOT NULL)
                BEGIN
                    SET @daysCount = @daysCount+1
                END

            -- Insert statements for procedure here
            SELECT * FROM (
                SELECT ROW_NUMBER() OVER
                (
                    ORDER BY
                    CASE WHEN @OrderBy = 'ND' THEN title END DESC,
                    CASE WHEN @OrderBy = 'NA' THEN title END,
                    CASE WHEN @OrderBy = '' THEN title END, 
                    CASE WHEN @OrderBy = 'RD' THEN authorRating END DESC,
                    CASE WHEN @OrderBy = 'RA' THEN authorRating
                ) AS Row,
                 Articles.ArticleId, Articles.userId, Articles.timestamp as datePosted, users.screenName, 
            defaultSmallImagePath, authorRating, ArticleCosts, title, 

            FROM Articles
            LEFT OUTER JOIN 
                Users on Articles.userId = Users.userId
            LEFT OUTER JOIN
                ArticleAdditionalInformation ON ArticleAdditionalInformation.ArticleId = Articles.ArticleId
            --JOIN FOR CONTINENT
            LEFT OUTER JOIN 
                Codings as Continent ON Continent.codingKeyId = ArticleAdditionalInformation.continentId AND Continent.languageId = @languageId
            -- JOIN FOR COUNTRY
            LEFT OUTER JOIN 
                CodingsAssociated as Country ON Country.codingKeyId = ArticleAdditionalInformation.countryId AND Country.languageId = @languageId
            -- JOIN FOR Article TRANSLATION DATA
            LEFT OUTER JOIN
                ArticlesTranslations ON ArticlesTranslations.ArticleId = Articles.ArticleId AND ArticlesTranslations.languageId=@languageId 
            LEFT OUTER JOIN
                ArticleCategories ON ArticleCategories.ArticleId = Articles.ArticleId

            WHERE   
                    (
                    ArticleCategories.categorieId =1 OR ArticleCategories.categorieId =2 OR 
                    ArticleCategories.categorieId =3 OR ArticleCategories.categorieId =4 OR 
                    ArticleCategories.categorieId = 5 
                    ) AND
                    (ArticlesTranslations.title LIKE '%' + @searchString + '%' OR @searchString IS NULL) 
                    -- COST filter
                    AND
                    (ArticleCosts < @cost OR @cost = 0)
                    AND
                    (ArticleCosts > 0 OR @cost = 0)
                    --END cost filter

                    -- EXCLUDE already stored for selected days 
                    AND Articles.ArticleId -- exclude these ArticleIds
                    NOT IN
                    (
                        SELECT DailyContent.ArticleId
                        FROM DailyContent
                        WHERE
                            sectionId=@sectionId AND 
                            (
                                weekDayId=@mon OR
                                weekDayId=@tue OR
                                weekDayId=@wed OR
                                weekDayId=@thu OR
                                weekDayId=@fri OR
                                weekDayId=@sat OR
                                weekDayId=@sun
                            )
                        GROUP BY
                            DailyContent.ArticleId
                        HAVING 
                            (COUNT(sectionId) = @daysCount)
                    )
                    -- END exclude

                    ) p
                    WHERE  (Row > @startRowIndex AND Row <=@startRowIndex + @pageSize)
            ORDER BY Row
        END

所以,当@includeFavourites参数不为空时,我只想在收藏表中包含唯一的articleIds。

任何提示都将非常感谢;)

我正在使用SQL Server 2008。

1 个答案:

答案 0 :(得分:0)

试试这个 -

DECLARE @daysCount INT 
SELECT @daysCount = 
    ISNULL(@mon, 0) + -- if @mon = 1, @tue = 2, .... 1 + (2-1)=1 + (3-2)=1 + ...
    ISNULL(@tue - 1, 0) +
    ISNULL(@wed - 2, 0) +
    ISNULL(@thu - 3, 0) +
    ISNULL(@fri - 4, 0) +
    ISNULL(@sat - 5, 0) + 
    ISNULL(@sun - 6, 0) 

SELECT * 
FROM (
    SELECT ROW_NUMBER() OVER
    (
        ORDER BY
        CASE WHEN @OrderBy = 'ND' THEN title END DESC,
        CASE WHEN @OrderBy IN ('NA', '') THEN title END,
        CASE WHEN @OrderBy = 'RD' THEN authorRating END DESC,
        CASE WHEN @OrderBy = 'RA' THEN authorRating
    ) AS [Row]
    , a.ArticleId
    , a.userId
    , a.[timestamp] as datePosted
    , u.screenName
    , defaultSmallImagePath
    , authorRating
    , ArticleCosts
    , title
FROM dbo.Articles a -- always use schema and alias
LEFT JOIN dbo.Users u on a.userId = u.userId -- OUTER is unnecessary
LEFT JOIN dbo.ArticleAdditionalInformation aai ON aai.ArticleId = a.ArticleId
LEFT JOIN dbo.Codings cd ON cd.codingKeyId = aai.continentId AND cd.languageId = @languageId
LEFT JOIN dbo.CodingsAssociated c ON c.codingKeyId = aai.countryId AND c.languageId = @languageId
LEFT JOIN dbo.ArticlesTranslations at ON at.ArticleId = a.ArticleId AND at.languageId = @languageId 
LEFT JOIN dbo.ArticleCategories ac ON ac.ArticleId = a.ArticleId
WHERE ac.categorieId IN (1, 2, 3, 4, 5) 
    AND (
              at.title LIKE '%' + @searchString + '%' 
            OR 
              @searchString IS NULL
        ) 
    AND (ArticleCosts < @cost OR @cost = 0)
    AND (ArticleCosts > 0 OR @cost = 0)
    AND a.ArticleId NOT IN (
        SELECT dc2.ArticleId
        FROM dbo.DailyContent dc2
        WHERE sectionId = @sectionId 
        AND (
                weekDayId % @daysCount = 0 -- possible it's works
                --weekDayId = @mon OR
                --weekDayId = @tue OR
                --weekDayId = @wed OR
                --weekDayId = @thu OR
                --weekDayId = @fri OR
                --weekDayId = @sat OR
                --weekDayId = @sun
        )
        GROUP BY dc2.ArticleId
        HAVING COUNT(sectionId) = @daysCount
    )
) p
WHERE [Row] BETWEEN @startRowIndex AND @startRowIndex + @pageSize
--ORDER BY [Row] -- ROW_COUNT already sorted your rows