如何在使用order by子句SQL Server 2014时使用union all

时间:2014-12-27 14:30:46

标签: sql sql-server tsql union sql-server-2014

这是我的查询,但是收到错误

错误

  

Msg 156,Level 15,State 1,Line 6
  关键字'order'附近的语法不正确。

     

第15行,第15行,第1行,第13行   关键字'order'附近的语法不正确。

     

Msg 156,Level 15,State 1,Line 20
  关键字'order'附近的语法不正确。

查询

(SELECT TOP 20 cl_RooSiteId,
               cl_CrawlOrgUrl
 FROM   tblCrawlUrls
 WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
        AND cl_DuplicateUrl_ByCanonical = 0
        AND cl_RooSiteId = 1
 ORDER  BY cl_LastCrawlDate ASC)
UNION ALL
(SELECT TOP 200 cl_RooSiteId,
                cl_CrawlOrgUrl
 FROM   tblCrawlUrls
 WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
        AND cl_DuplicateUrl_ByCanonical = 0
        AND cl_RooSiteId = 2
 ORDER  BY cl_LastCrawlDate ASC)
UNION ALL
(SELECT TOP 50 cl_RooSiteId,
               cl_CrawlOrgUrl
 FROM   tblCrawlUrls
 WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
        AND cl_DuplicateUrl_ByCanonical = 0
        AND cl_RooSiteId = 3
 ORDER  BY cl_LastCrawlDate ASC) 

那么如何以一种应该有效的方式编写呢?

3 个答案:

答案 0 :(得分:4)

假设您按照您编写的顺序想要这些:

SELECT cl_RooSiteId, cl_CrawlOrgUrl
FROM ((SELECT TOP 20 cl_RooSiteId, cl_CrawlOrgUrl, cl_LastCrawlDate, 0 as priority
       FROM   tblCrawlUrls
       WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate) AND
              cl_DuplicateUrl_ByCanonical = 0 AND
              cl_RooSiteId = 1
      ) UNION ALL
      (SELECT TOP 200 cl_RooSiteId, cl_CrawlOrgUrl, cl_LastCrawlDate, 1 as priority
       FROM   tblCrawlUrls
       WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate) AND
              cl_DuplicateUrl_ByCanonical = 0 AND
              cl_RooSiteId = 2
      ) UNION ALL
      (SELECT TOP 50 cl_RooSiteId, cl_CrawlOrgUrl, cl_LastCrawlDate, 2
       FROM   tblCrawlUrls
       WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate) AND
              cl_DuplicateUrl_ByCanonical = 0 AND
              cl_RooSiteId = 3
      )
    ) c
ORDER BY priority, cl_LastCrawlDate ASC

请注意,子查询中包含prioritycl_LastCrawlDate。我意识到priority是多余的,因为您可以使用ORDER BY cl_RooSiteId, cl_LastCrawlDate

编辑:

您也可以在不union all的情况下执行此操作:

SELECT cl_RooSiteId, cl_CrawlOrgUrl
FROM (SELECT c.*,
             ROW_NUMBER() OVER (PARTITION BY cl_RooSiteId ORDER BY cl_LastCrawlDate) as seqnum
      FROM tblCrawlUrls c
      WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate) AND
             cl_DuplicateUrl_ByCanonical = 0
     ) c
WHERE (cl_RooSiteId = 1 and seqnum <= 20) OR
      (cl_RooSiteId = 2 and seqnum <= 200) OR
      (cl_RooSiteId = 3 and seqnum <= 50)
ORDER BY cl_RooSiteId, cl_LastCrawlDate;

答案 1 :(得分:1)

将查询结果复制到temp table并使用Union all

SELECT TOP 20 cl_RooSiteId,
              cl_CrawlOrgUrl,cl_LastCrawlDate
INTO   #Temp1
FROM   tblCrawlUrls
WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
       AND cl_DuplicateUrl_ByCanonical = 0
       AND cl_RooSiteId = 1
ORDER  BY cl_LastCrawlDate ASC

SELECT TOP 200 cl_RooSiteId,
               cl_CrawlOrgUrl,cl_LastCrawlDate
INTO   #temp2
FROM   tblCrawlUrls
WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
       AND cl_DuplicateUrl_ByCanonical = 0
       AND cl_RooSiteId = 2
ORDER  BY cl_LastCrawlDate ASC

SELECT TOP 50 cl_RooSiteId,
              cl_CrawlOrgUrl,cl_LastCrawlDate
INTO   #temp3
FROM   tblCrawlUrls
WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
       AND cl_DuplicateUrl_ByCanonical = 0
       AND cl_RooSiteId = 3
ORDER  BY cl_LastCrawlDate ASC

SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   #Temp1
UNION ALL
SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   #Temp2
UNION ALL
SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   #Temp3 
Order by cl_LastCrawlDate 

或使用Stacked CTE

;WITH cte1
     AS (SELECT TOP 20 cl_RooSiteId,
                       cl_CrawlOrgUrl,cl_LastCrawlDate
         FROM   tblCrawlUrls
         WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
                AND cl_DuplicateUrl_ByCanonical = 0
                AND cl_RooSiteId = 1
         ORDER  BY cl_LastCrawlDate ASC),
     cte2
     AS (SELECT TOP 200 cl_RooSiteId,
                        cl_CrawlOrgUrl,cl_LastCrawlDate
         FROM   tblCrawlUrls
         WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
                AND cl_DuplicateUrl_ByCanonical = 0
                AND cl_RooSiteId = 2
         ORDER  BY cl_LastCrawlDate ASC),
     cte3
     AS (SELECT TOP 50 cl_RooSiteId,
                       cl_CrawlOrgUrl,cl_LastCrawlDate
         FROM   tblCrawlUrls
         WHERE  Sysutcdatetime() > Dateadd(MINUTE, 50000, cl_LastCrawlDate)
                AND cl_DuplicateUrl_ByCanonical = 0
                AND cl_RooSiteId = 3
         ORDER  BY cl_LastCrawlDate ASC)
SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   cte1
UNION ALL
SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   cte2
UNION ALL
SELECT cl_RooSiteId,cl_CrawlOrgUrl FROM   cte3 
ORDER  BY cl_LastCrawlDate ASC

答案 2 :(得分:1)

常见的表格表达式应该是技巧SEE THIS LINK

公用表表达式(CTE)可以被认为是在单个SELECT,INSERT,UPDATE,DELETE或CREATE VIEW语句的执行范围内定义的临时结果集。 CTE类似于派生表,因为它不作为对象存储,并且仅在查询期间持续。与派生表不同,CTE可以是自引用的,并且可以在同一查询中多次引用。

这是一个片段

WITH TopLevel( colum1, column2, ...) AS 
(
   SELECT column1, column2, ...
   FROM table1  --without ORDER BY

   UNION ALL

   SELECT column1, column2, ...
   FROM table2 --without ORDER BY
   .
   .
   .

)
SELECT * FROM 
FROM TopLevel
ORDER BY column1, column2... --ORDER BY HERE...