与 UNION 一起使用时,对每个 SQL Server 查询都不起作用的排序
Posted
技术标签:
【中文标题】与 UNION 一起使用时,对每个 SQL Server 查询都不起作用的排序【英文标题】:Sort on each SQL Server query not working when used with UNION 【发布时间】: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 版本,请查看他的答案。
【问题讨论】:
【参考方案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
我又做了一个改动,你能试试并告诉我吗?以上是关于与 UNION 一起使用时,对每个 SQL Server 查询都不起作用的排序的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server:如何将 UNION 与两个都有 WHERE 子句的查询一起使用?