【问题标题】:How to use union all when using order by clause SQL Server 2014使用 order by 子句 SQL Server 2014 时如何使用 union all
【发布时间】:2014-12-27 14:30:46
【问题描述】:

这是我的查询,但出现错误

错误

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

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

消息 156,第 15 级,状态 1,第 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) 

那么应该如何编写它应该可以工作呢?

【问题讨论】:

  • 你不能在 UNION (ALL) 之间下订单,创建一个顶级 SELECT 然后在那里下订单。
  • @agentpx 那么我怎样才能实现我想要实现的目标呢?我也尝试将它们封装在上层选择中,但它也失败了
  • ty 我看到 MSSQL 无法满足我的要求,因此最好将每个查询作为表返回,然后在我的代码后面处理。每个查询都需要单独排序,而不是返回结果。

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


【解决方案1】:

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

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;

【讨论】:

  • 合并结果的顺序并不重要。只有单独的选择顺序对于首先检索未抓取的 url 很重要。您的第二个查询不起作用也给出错误消息 156,级别 15,状态 1,第 8 行关键字“WHERE”附近的语法不正确。
  • 只给派生表一个名字)derivedTable
  • 这值得检查 +1
【解决方案2】:

将查询结果复制到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

【讨论】:

  • ty for answer already tried that it is not working 错误:如果语句包含 UNION、INTERSECT 或除了运算符。
  • @MonsterMMORPG - 更新试试吧。
  • ty 我看到 MSSQL 无法满足我的要求,因此最好将每个查询作为表返回,然后在我的代码后面处理。每个查询都需要单独排序,而不是返回结果。
  • 好的,这似乎工作得很好,但是我需要在每个查询中删除临时表,同时使用临时表似乎给 sql server 带来了很多额外的开销
  • @MonsterMMORPG - 现在检查你也可以使用stacked CTE
【解决方案3】:

公用表表达式应​​该可以解决问题SEE THIS LINK

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

这是一个sn-ps

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...

【讨论】:

  • ty 我看到 MSSQL 无法满足我的要求,因此最好将每个查询作为表返回,然后在我的代码后面处理。每个查询都需要单独排序,而不是返回结果。
猜你喜欢
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多