【问题标题】:Sort on each SQL Server query not working when used with UNION与 UNION 一起使用时,对每个 SQL Server 查询都不起作用的排序
【发布时间】:2012-12-23 03:11:48
【问题描述】:

我必须合并来自 3 个具有不同列的不同表的数据,并且我想要的输出应该基于每个表的不同排序条件。

我在下面使用此查询,但此查询根据菜单位置对整体结果进行排序,如何更改此查询以对单个查询的结果进行排序

SELECT DISTINCT 
     PID, MENU, Handler, PageLangID, ParentID, IssueID, CatID, MenuPosition 
FROM (
   --Pages Table 
   SELECT TOP 50 
       PageId AS PID,SUBSTRING(PageName,0,20) AS MENU,SUBSTRING(PageInternalLinkURL,0,24) AS Handler, PageLangID,PageInheritance AS ParentID, 1 AS IssueID, 1 AS CatID, 
        PageLinkPosition as MenuPosition  FROM pg_Pages  WHERE PageLangID = 1  ORDER BY PageLinkPosition DESC 
UNION 
--Article Category Table
SELECT TOP 20 p.PageID AS PID, SUBSTRING(c.ArticleCategoryName,0,20) AS MENU,SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler, 
c.LangID,p.PageID,1, ArticleCategoryID, 1 AS MenuPosition FROM art_Category c JOIN pg_Pages p 
ON c.PageID = p.PageID  JOIN art_CategoryType ct ON c.Type = ct.CategoryTypeID WHERE c.LangID =1  AND c.Type =1 
ORDER BY c.ArticleCategoryName  
UNION 
--Magazine Table
SELECT TOP 10 p.PageID AS PID, CAST(IssueCode AS varchar(10)),SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler,LangID,p.PageID AS ParentID, m.IssueID AS IssueID, 1, 
       1 AS MenuPosition FROM Magazine m   JOIN pg_pages p ON m.PageID = p.PageID   WHERE LangID =1  ORDER BY 2 DESC  
) AS T  WHERE T.PageLangID = 1 ORDER BY MenuPosition

第二种方式

如果我使用以下查询,则会出现以下错误

消息 156,第 15 级,状态 1,第 4 行
关键字“UNION”附近的语法不正确。
消息 156,第 15 级,状态 1,第 10 行
关键字“UNION”附近的语法不正确。

查询

--Pages Table 
SELECT TOP 50 PageId AS PID,SUBSTRING(PageName,0,20) AS MENU,SUBSTRING(PageInternalLinkURL,0,24) AS Handler, PageLangID,PageInheritance AS ParentID, 1 AS IssueID, 1 AS CatID, 
        PageLinkPosition as MenuPosition  FROM pg_Pages  WHERE PageLangID = 1  ORDER BY PageLinkPosition DESC 
UNION 
--Article Category Table
SELECT TOP 20 p.PageID AS PID, SUBSTRING(c.ArticleCategoryName,0,20) AS MENU,SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler, 
c.LangID,p.PageID,1, ArticleCategoryID, 1 AS MenuPosition FROM art_Category c JOIN pg_Pages p 
ON c.PageID = p.PageID  JOIN art_CategoryType ct ON c.Type = ct.CategoryTypeID WHERE c.LangID =1  AND c.Type =1 
ORDER BY c.ArticleCategoryName  ASC
UNION 
--Magazine Table
SELECT TOP 10 p.PageID AS PID, CAST(IssueCode AS varchar(10)),SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler,LangID,p.PageID AS ParentID, m.IssueID AS IssueID, 1, 
       1 AS MenuPosition FROM Magazine m   JOIN pg_pages p ON m.PageID = p.PageID   WHERE LangID =1  ORDER BY 2 DESC  

样本数据

PID         MENU                 Handler                  PageLangID  ParentID    IssueID     CatID       MenuPosition
----------- -------------------- ------------------------ ----------- ----------- ----------- ----------- ------------
6           Book Review          Page.aspx                1           6           1           18          1
6           Business             Page.aspx                1           6           1           16          1
6           Culture              Page.aspx                1           6           1           3           1
6           Economy              Page.aspx                1           6           1           2           1
6           Finance              Page.aspx                1           6           1           19          1
6           Infrastructure       Page.aspx                1           6           1           17          1
6           Lifestyle            Page.aspx                1           6           1           20          1
6           Others               Page.aspx                1           6           1           21          1
6           People               Page.aspx                1           6           1           7           1
6           Politics             Page.aspx                1           6           1           1           1
6           Sports               Page.aspx                1           6           1           4           1
12          102                  Page.aspx                1           12          3           1           1
12          103                  Page.aspx                1           12          4           1           1
12          106                  Page.aspx                1           12          1           1           1
12          109                  Page.aspx                1           12          5           1           1
1           Home                 Default.aspx             1           0           1           1           10
11          Video                Videos.aspx              1           10          1           1           10
2           About Us             Page.aspx                1           0           1           1           20
5           Articles             Articles.aspx            1           0           1           1           30
6           Categories           Page.aspx                1           0           1           1           40
12          Archive              Page.aspx                1           0           1           1           50
3           News                 News.aspx                1           0           1           1           60
10          Multimedia           Multimedia.aspx          1           0           1           1           70

我希望第一个查询按 ORDER BY PageLinkPosition DESC 排序

ORDER BY c.ArticleCategoryName ASC排序的第二个查询

第三个查询按ORDER BY IssueCode DESC排序

我尝试了很多方法,但无法正常工作。

感谢这方面的帮助

更新:基于标记解决方案的工作查询并进行小幅改动

SELECT DISTINCT PID, MENU, Handler, PageLangID, ParentID, IssueID, CatID, MenuPosition, block, rNum
FROM    
(   --Pages Table 
    SELECT TOP 50 
        PageId AS PID,SUBSTRING(PageName,0,20) AS MENU,SUBSTRING(PageInternalLinkURL,0,24) AS Handler, PageLangID,PageInheritance AS ParentID, 1 AS IssueID, 1 AS CatID, 
        PageLinkPosition as MenuPosition
        ,Block = 1
        ,rNum = ROW_NUMBER() OVER (ORDER BY PageLinkPosition DESC)  
    FROM pg_Pages  
    WHERE PageLangID = 1  
    UNION ALL   -- Better to UNION ALL and then DISTINCT outside
--Article Category Table
    SELECT TOP 20 
        p.PageID AS PID, SUBSTRING(c.ArticleCategoryName,0,20) AS MENU,SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler, 
        c.LangID,p.PageID,1, ArticleCategoryID, 1 AS MenuPosition
        ,Block = 2 
        ,rNum = ROW_NUMBER() OVER (ORDER BY c.ArticleCategoryName )
    FROM art_Category c 
    JOIN pg_Pages p             ON c.PageID = p.PageID  
    JOIN art_CategoryType ct    ON c.Type = ct.CategoryTypeID 
    WHERE c.LangID =1  AND c.Type =1 
    UNION ALL
--Magazine Table
    SELECT TOP 10 p.PageID AS PID, CAST(IssueCode AS varchar(10)),SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler,LangID,p.PageID AS ParentID, m.IssueID AS IssueID, 1, 
       1 AS MenuPosition
       ,Block = 3 
       ,rNum = ROW_NUMBER() OVER (ORDER BY CAST(IssueCode AS varchar(10))DESC)
    FROM Magazine m   
    JOIN pg_pages p ON m.PageID = p.PageID   
    WHERE LangID =1  
) AS T  WHERE T.PageLangID = 1 
ORDER BY Block, rNum

MARK 稍后将他的解决方案更新为 CTE 版本,请查看他的答案。

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql greatest-n-per-group


    【解决方案1】:

    这应该有效;

    ;WITH CTE AS
    (
        SELECT TOP 50 
             PageId AS PID
            ,SUBSTRING(PageName,0,20) AS MENU
            ,SUBSTRING(PageInternalLinkURL,0,24) AS Handler
            ,PageLangID
            ,PageInheritance AS ParentID
            ,1 AS IssueID
            ,1 AS CatID
            ,PageLinkPosition as MenuPosition
            ,Block = 1
            ,rNum = ROW_NUMBER() OVER (ORDER BY PageLinkPosition DESC)  
        FROM pg_Pages  
        WHERE PageLangID = 1  
        UNION ALL   
    --Article Category Table
        SELECT TOP 20 
             p.PageID AS PID
            ,SUBSTRING(c.ArticleCategoryName,0,20) AS MENU
            ,SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler
            ,c.LangID
            ,p.PageID
            ,1
            ,ArticleCategoryID
            ,1 AS MenuPosition
            ,Block = 2 
            ,rNum = ROW_NUMBER() OVER (ORDER BY c.ArticleCategoryName )
        FROM art_Category c 
        JOIN pg_Pages p             ON c.PageID = p.PageID  
        JOIN art_CategoryType ct    ON c.Type = ct.CategoryTypeID 
        WHERE c.LangID =1  AND c.Type =1 
        UNION ALL
    --Magazine Table
        SELECT TOP 10 
             p.PageID AS PID
            ,CAST(IssueCode AS varchar(10))
            ,SUBSTRING(p.PageInternalLinkURL,0,24) AS Handler
            ,LangID
            ,p.PageID AS ParentID
            ,m.IssueID AS IssueID
            ,1
            ,1 AS MenuPosition
            ,Block = 3 
            ,rNum = ROW_NUMBER() OVER (ORDER BY CAST(IssueCode AS varchar(10)))
        FROM Magazine m   
        JOIN pg_pages p ON m.PageID = p.PageID   
        WHERE LangID =1  
    )
    ,Deduplicate AS
    (
        SELECT   PID
                ,MENU
                ,Handler
                ,PageLangID
                ,ParentID
                ,IssueID
                ,CatID
                ,MenuPosition 
                ,Block
                ,rNum
                ,Occ = ROW_NUMBER() OVER (PARTITION BY PID, MENU, Handler, PageLangID, ParentID, IssueID, CatID, MenuPosition ORDER BY (SELECT NULL))
        FROM CTE
    )
    SELECT  PID
           ,MENU
           ,Handler
           ,PageLangID
           ,ParentID
           ,IssueID
           ,CatID
           ,MenuPosition 
    FROM Deduplicate
    WHERE Occ = 1
    ORDER BY Block, rNum
    

    【讨论】:

    • 我收到此错误Msg 145, Level 15, State 1, Line 1 ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
    • 如果我忽略 Order by 子句,那么它会得到结果并且显然不是预期的。查询的最后一部分生成错误ORDER BY Block, rNum
    • 我删除了外部DISTINCT 并使用UNION 而不是UNION ALL。你现在遇到什么错误?
    • 我通过在第一行的 SELECT 部分添加 Block, rNum 使其工作,并通过添加排序类型 ASC 或 DESC 进行小改动以获得所需的结果.. 我仍在测试它.. ++ UPDATE++ `ORDER BY CAST(IssueCode AS varchar(10))DESC
    • 我又做了一个改动,你能试试并告诉我吗?
    猜你喜欢
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 2011-04-13
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多