【问题标题】:Optimize and reduce size of Union Select Query优化并减小 Union Select Query 的大小
【发布时间】:2020-09-13 02:55:37
【问题描述】:

我的问题是关于如何优化和减小 sql 查询的大小。我想使用 UNION 加入 20 多个查询,它根据以下逻辑给了我正确的结果,但我在这里寻找两件事

  • 更高效的方法

  • 我的查询中已经有 20 个 UNION,并且每个月我都必须添加 2-4 个 UNION,这使得这个查询很长,所以有什么办法可以用更少的代码来改写这个查询

     Select 
     '343' As 'Manual ID',
     '24/07/2020' As 'Date',
     A.ID,
     O.Order_Name,
     C.Customer_Name,
     Q.Quantity
     From Shipper A
     Left Join Order O  A.ID = O.ID
     Left Join Customer C A.ID = C.ID
     Left Join Quantity Q Q.ID = C.ID
     where A.ID IN (1)
    
     UNION
    
     Select 
     '323' As 'Manual ID',
     '24/08/2020' As 'Date',
     A.ID,
     O.Order_Name,
     C.Customer_Name,
     Q.Quantity
     From Shipper A
     Left Join Order O A.ID = O.ID
     Left Join Customer C A.ID = C.ID
     Left Join Quantity Q Q.ID = C.ID
     where A.ID IN(2,3,4)
    

    等等……

结果

Manual ID | Date       | Shipper | Order Name | Customer Name | Qty
343       | 24/07/2020 |   1     |   order1   |      A        |  5
323       | 24/08/2020 |   2     |   order2   |      B        |  2
323       | 24/08/2020 |   3     |   order3   |      C        |  1
323       | 24/08/2020 |   4     |   order4   |      D        |  12

【问题讨论】:

  • 除了建议所有涉及的表的ID 列上都有索引之外,我没有看到任何明显的方法可以使联合更快。也就是说,我建议您尝试优化单个查询,如果您还没有这样做的话。
  • 感谢您的快速响应,每当添加新的托运人时,我都必须从 UNION 复制。我有 20 多个 UNION,这使查询变得很长,并且每周添加 1 或 2 个 UNION,任何建议如何改写此查询
  • 样本数据、您期望从该数据中获得的输出以及对您要解决的问题的更清晰解释会有所帮助。
  • 由于每个联合之间的唯一变量似乎是Manual IDDateA.ID,因此您可以制作一个报告表,其中每一行都是这些变体之一。然后创建一个查询,该查询选择所有报告表行并输出由最终 SQL 查询组成的字符串。这不会使最终查询更加高效,但它会使创建查询的过程更加高效。
  • 您如何定义手动 id,日期是针对特定托运人 id 的?在您的示例中,发货人 ID 1 的日期为 2020 年 7 月 24 日,手动 ID 为 343。您是如何得出这个的?

标签: mysql sql left-join union toad


【解决方案1】:

你可以试试这个:

Select
 CASE
    WHEN A.ID IN(1) THEN '343'
    WHEN A.ID IN(2,3,4) THEN '323'
 END As 'Manual ID',
 CASE
    WHEN A.ID IN(1) THEN '24/07/2020'
    WHEN A.ID IN(2,3,4) THEN '24/08/2020'
 END As 'Date',
 A.ID,
 O.Order_Name,
 C.Customer_Name,
 Q.Quantity
 From Shipper A
 Left Join Order O  A.ID = O.ID
 Left Join Customer C A.ID = C.ID
 Left Join Quantity Q Q.ID = C.ID
 Where A.ID IN(1,2,3,4)

【讨论】:

  • 谢谢,Soumendra 但这又是一个长度查询
  • 你能分享一下结果,看看出了什么问题吗?
  • 当我运行查询时,它显示了数据库中的所有结果;根据要求,它应该只向我展示 AID - 1、2、3、4。抱歉无法分享结果
  • 更新上述评论:当我运行查询时,它显示了数据库中的所有结果(900,000);根据要求,它应该只显示 4 条记录 AID - 1、2、3、4。抱歉无法分享结果
  • 如果它解决了问题,请考虑投票并接受它!
【解决方案2】:

第一个建议是将参数移动到另一个表中,然后加入它。如果您不想使用真正的表格,您甚至可以将其设为内联视图...

第二个建议是使用 UNION ALL 来避免 UNION 产生的重复数据删除成本。

SELECT
    params.*, 
    O.Order_Name,
    C.Customer_Name,
    Q.Quantity
FROM
(
              SELECT '343' As 'Manual ID', '24/07/2020' As 'Date', 1 AS A_ID
    UNION ALL SELECT '323' As 'Manual ID', '24/08/2020' As 'Date', 2 AS A_ID
    UNION ALL SELECT '323' As 'Manual ID', '24/08/2020' As 'Date', 3 AS A_ID
    UNION ALL SELECT '323' As 'Manual ID', '24/08/2020' As 'Date', 4 AS A_ID
)
  AS params
 INNER JOIN Shipper A ON A.ID = params.A_ID
 Left Join Order O ON A.ID = O.ID
 Left Join Customer C ON C A.ID = C.ID
 Left Join Quantity Q ON Q.ID = C.ID

或者,不要每个月都重新计算。每个月编写一个新查询,并将结果插入另一个表?

【讨论】:

  • 谢谢,MatBaillie,是否可以将 A_ID(2,3,4) 添加到一行而不是单独的行中。类似于 - 选择“323”作为“手动 ID”、“24/08/2020”作为“日期”、2、3、4 作为 A_ID
【解决方案3】:

如果您只是想进行查询,更好的方法是使用 case when 语句,但您需要不时更新查询以添加新案例。

另一个优化的解决方案是创建一个新表来存储 Manual ID, Date, (Common) ID 出现在 Shipper(表)中。然后创建一个视图,将以上所有表与新表连接起来。

新建表格

Manual ID | Date       |   ID    |
343       | 24/07/2020 |   1     |
323       | 24/08/2020 |   2     |
323       | 24/08/2020 |   3     |
323       | 24/08/2020 |   4     |

然后创建一个视图加入所有表,包括具有 ID 的新表。

在此您只需向新表添加新值,您将在自己的视图中完成结果。

CREATE VIEW MY_VIEW
AS
SELECT * FROM
(
 Select 
 T.[Manual ID],
 T.[Date],
 A.ID,
 O.Order_Name,
 C.Customer_Name,
 Q.Quantity
 From Shipper A
 Left Join Order O  A.ID = O.ID
 Left Join Customer C A.ID = C.ID
 Left Join Quantity Q Q.ID = C.ID
 Left Join NewTable T T.ID = A.ID
 )

现在只需在新表中插入值并从 MY_VIEW 获取完整数据。它会给出与您例外的结果相同的结果。

【讨论】:

  • 感谢 Abhishek,是否可以在 Excel 中创建视图并从那里提供给这个 SQL 查询(在 Toad 中)?
  • 是的,可以像创建视图一样连接多个工作表。观看此视频 - youtube.com/watch?v=325GKIXPsSI&t=40s。是的,您可以通过“导入”选项通过 SSMS 将数据从 excel 上传到 sql。
猜你喜欢
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
相关资源
最近更新 更多