【问题标题】:UNION Query with ORDER BY SUM使用 ORDER BY SUM 的 UNION 查询
【发布时间】:2018-11-09 02:05:41
【问题描述】:

这是我想做的:

SELECT 
  TOP 25 tblTasks.Task, 
  tblTasks.Task_Status, 
  tblTasks.Award_Date, 
  tblTasks.End_Date, 
  Sum(tblPRs.Ceiling_Final) AS SumOfCeiling_Final, 
  tblTasks.Program, tblTasks.Prime, tblClient.Org_Top
FROM 
  (tblTasks INNER JOIN tblClient ON tblTasks.Task_ID = tblClient.Task_ID) 
   INNER JOIN tblPRs ON tblTasks.Task_ID = tblPRs.Task_ID
GROUP BY 
   tblTasks.Task, 
   tblTasks.Task_Status, 
   tblTasks.Award_Date, 
   tblTasks.End_Date, 
   tblTasks.Program, 
   tblTasks.Prime, tblClient.Org_Top
HAVING 
   (((tblTasks.Task_Status)="open"))

UNION

SELECT 
   TOP 25 tblTasks.Task, 
   tblTasks.Task_Status, 
   tblTasks.Award_Date, 
   tblTasks.End_Date, Sum(tblPRs.Ceiling_Final) AS SumOfCeiling_Final, 
   tblTasks.Program, 
   tblTasks.Prime, tblClient.Org_Top
FROM 
   (tblTasks INNER JOIN tblClient ON tblTasks.Task_ID = tblClient.Task_ID) 
    INNER JOIN tblPRs ON tblTasks.Task_ID = tblPRs.Task_ID
GROUP BY 
    tblTasks.Task, 
    tblTasks.Task_Status, 
    tblTasks.Award_Date, 
    tblTasks.End_Date, 
    tblTasks.Program, 
    tblTasks.Prime, 
    tblClient.Org_Top
HAVING 
    (((tblTasks.Task_Status)="pending"))

ORDER BY 
    Sum(tblPRs.Ceiling_Final) DESC;

我正在将 SQL 输入 MS Access。两个查询之间的唯一区别是 HAVING 参数值。单个查询来自 MS Access 查询设计。与 ORDER BY 语句配对时,每个单独的查询都可以正常工作并给我预期的结果。当我尝试将它们都作为 UNION 运行时,出现以下错误:

ORDER BY 表达式 (Sum(tblPRs.Ceiling_Final)) 包括字段 查询未选择的。只有那些请求的字段 第一个查询可以包含在 ORDER BY 表达式中。

【问题讨论】:

  • 您是否希望 从 2 个查询中的每个 中获得 25 行(总共 50 行)?还是只想要前 25 名?
  • 每个 25 个,总共 50 个。我实际上可以将第二个查询更改为 10 个,总共 35 个。
  • 感谢版主清理我的帖子。

标签: sql database ms-access sql-order-by union


【解决方案1】:

nb:我假设您只想要 SumOfCeiling_Final 最高的 25 行

我建议您应该首先使用union all 形成一个“派生表”,然后查找top n 行。请注意having clause 不能替代where clause。如果过滤条件需要聚合值(例如 having sum(cost) > 1000 ),则 having clause 是必需的。如果过滤条件不涉及聚合,请将它们放在where clause 中。

SELECT TOP 25
    *
FROM (
    SELECT
        tblTasks.Task, tblTasks.Task_Status, tblTasks.Award_Date, tblTasks.End_Date, SUM(tblPRs.Ceiling_Final) AS SumOfCeiling_Final, tblTasks.Program, tblTasks.Prime, tblClient.Org_Top
    FROM (tblTasks
    INNER JOIN tblClient
        ON tblTasks.Task_ID = tblClient.Task_ID)
    INNER JOIN tblPRs
        ON tblTasks.Task_ID = tblPRs.Task_ID
    WHERE tblTasks.Task_Status = "open"
    GROUP BY
        tblTasks.Task
       ,tblTasks.Task_Status
       ,tblTasks.Award_Date
       ,tblTasks.End_Date
       ,tblTasks.Program
       ,tblTasks.Prime
       ,tblClient.Org_Top

    UNION ALL

    SELECT
        tblTasks.Task, tblTasks.Task_Status, tblTasks.Award_Date, tblTasks.End_Date, SUM(tblPRs.Ceiling_Final) AS SumOfCeiling_Final, tblTasks.Program, tblTasks.Prime, tblClient.Org_Top
    FROM (tblTasks
    INNER JOIN tblClient
        ON tblTasks.Task_ID = tblClient.Task_ID)
    INNER JOIN tblPRs
        ON tblTasks.Task_ID = tblPRs.Task_ID
    WHERE tblTasks.Task_Status = "pending"
    GROUP BY
        tblTasks.Task
       ,tblTasks.Task_Status
       ,tblTasks.Award_Date
       ,tblTasks.End_Date
       ,tblTasks.Program
       ,tblTasks.Prime
       ,tblClient.Org_Top
    ) d
ORDER BY
    SumOfCeiling_Final DESC
;

NB UNION ALL 不会删除重复的行,UNION 会删除重复的行。所以,UNION ALL 实际上做了更少的工作,即它更快。此外,在上层查询中,每行都必须包含 Task_Status = "open",而下层查询中必须包含 Task_Status = "pending",因此这两个查询产生的行必须不同。虽然没有数据可以验证我无法确定,但看来你只需要使用union all即可。

【讨论】:

  • 我很确定我之前尝试过使用派生表解决该问题。在我看来,我收到一条错误消息,指出 FROM 语法存在问题。我将在上午的工作中尝试解决方案。另外,我需要每个查询的前 25 名。这将如何改变你的所作所为? HAVING 子句是由 MS Design Query 创建的——我不知道为什么。我认为它也应该是一个 WHERE。
  • 在家里发现了一份陈旧的数据库副本。我尝试了您的解决方案,它似乎有效。我还将 SELECT TOP 25 移动到两个原始查询中(给我 50 行)。我对陈旧的数据库有疑问,所以我无法确定我是否完全按照我想要的方式获取数据。好消息是它正在运行,我认为我现在走在正确的轨道上。我不确定为什么我之前尝试使用与您相同的方法失败了 - 我在某处遇到了语法问题。谢谢!!
  • 因此将 TOP 25 从外部移动到每个内部查询都会给我随机结果(查询运行但数据不是我所期望的)。我们如何修改您的解决方案,为每个内部查询提供 TOP 25?
  • 解决方案似乎是将每个 SELECT TOP 查询(包括 ORDER BY)放入其自己的派生表中,然后 UNION ALL 派生表。我有这个工作在一个最小的模式上。申请到我的活动数据库后,我将发布最终解决方案(如果可行)。
【解决方案2】:

我相信以下其中一项将完成您所追求的目标:

SELECT *
FROM (put your 1st query here
      UNION
      put your 2nd query here)
ORDER BY SumOfCeiling_Final DESC;

-或-

SELECT * FROM (put your 1st query here, and include ORDER BY Sum(tblPRs.Ceiling_Final) DESC)
UNION
SELECT * FROM (put your 2nd query here, and include ORDER BY Sum(tblPRs.Ceiling_Final) DESC)

我的 sql-fu 不够强大,无法确定这些是否可行,而无需摆弄实际数据;说到这里,你能用最少的模式和数据设置一个 SQL Fiddle 来说明你的问题吗?

编辑:为了记录,我也喜欢@Used_By_Already 发布的答案,显然他/她的答案非常像我的第一个选择;使用最适合您需求的那个。

【讨论】:

  • 我是个真正的菜鸟。不知道如何设置小提琴。如果你解释一下,我可以试试。此外,正如我之前对先前答案的评论一样,我很确定我试图让这个解决方案工作,但得到一个与 FROM 语法相关的错误。明天试试。
  • @John 1. 转到SQL Fiddle 2. 在左侧,输入模式语句(CREATE TABLE 等)和数据填充语句(INSERT 等),然后单击“构建模式” ” 3.在右侧,输入查询并点击“运行SQL” 4.修补
  • @John 请注意,您可以选择 RDBMS;我不认为你正在尝试任何对特定 RDBMS 过于具体的东西,所以他们中的任何一个都应该这样做......我相信
【解决方案3】:

我最终将每个查询放入派生表中,然后对派生表执行 UNION。

SELECT *
FROM ( placed first query here including the ORDER BY
) AS a

UNION ALL

SELECT *
FROM ( placed second query here including the ORDER BY
) AS b;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 2011-09-17
    • 2023-03-24
    相关资源
    最近更新 更多