【问题标题】:I have two SQL queries. I need to join them into a single SQL query我有两个 SQL 查询。我需要将它们加入到单个 SQL 查询中
【发布时间】:2022-01-03 12:33:36
【问题描述】:

我有两个 sql 查询需要合并为一个。当我试图将这两个查询组合成一个查询时,我没有得到正确的结果。请有人帮忙将这两个查询组合成一个查询。

第一个 SQL 查询:

SELECT distinct order_no,status,status_cd,
case when order_qty - fulfilled_qty > 0 then 'inventory-unavailable' END
from t1 a, t2 b
where 
a.inventory_stockout='TRUE'
AND a.flag_column='TRUE' 
and status in '(fulfilled','pending')
GROUP BY order_no,status,status_cd;

第二个 SQL 查询:

SELECT distinct order_no,status,status_cd,
case when order_qty - fulfilled_qty > 0 then 'inventory-unavailable' END
from t1 a, t2 b
where 
a.inventory_stockout='TRUE'
AND a.flag_column='TRUE' 
and a.subscription_enabled='TRUE'
GROUP BY order_no,status,status_cd;

【问题讨论】:

  • MySQL 我想...?
  • 今日提示:始终使用现代、明确的JOIN 语法!更容易编写(没有错误),更容易阅读和维护,如果需要更容易转换为外连接
  • 您的查询在多个方面无效,并且可能不会产生您认为他们正在执行的结果。这是你的主要问题!

标签: mysql sql oracle snowflake-cloud-data-platform


【解决方案1】:

如果他们两个——分别——返回你想要的结果(我怀疑;你在t1t2之间使用交叉连接),那么一个简单的选择是union他们(删除@987654324 @,删除 group by(无论如何都没有意义,因为您没有聚合任何内容,但 distinct 完成了这项工作)因为 union 在这种情况下替换了它们两者):

SELECT order_no,
       status,
       status_cd,
       CASE
          WHEN order_qty - fulfilled_qty > 0 THEN 'inventory-unavailable'
       END
  FROM t1 a, t2 b
 WHERE     a.inventory_stockout = 'TRUE'
       AND a.flag_column = 'TRUE'
       AND status IN ('fulfilled', 'pending')
UNION
SELECT order_no,
       status,
       status_cd,
       CASE
          WHEN order_qty - fulfilled_qty > 0 THEN 'inventory-unavailable'
       END
  FROM t1 a, t2 b
 WHERE     a.inventory_stockout = 'TRUE'
       AND a.flag_column = 'TRUE'
       AND a.subscription_enabled = 'TRUE';

【讨论】:

  • 或者做一个SELECT DISTINCT,和... AND (status IN ('fulfilled', 'pending') OR a.subscription_enabled = 'TRUE');
  • 非常感谢您的帮助:)
  • 如果以上答案解决了您的问题,那么请接受其中一个。这有助于未来有类似问题的提问者,并从未回答的队列中删除问题。请不要将成功回答的问题留作未回答。
【解决方案2】:

一个问题:我看到了 t1 和 t2 以及同义词,但没有看到连接条件或将 t1 和 t2 连接在一起的关键逻辑。你知道这些表之间的PK/FK关系是什么吗?

建议:您使用大多数相同的条件和相同的案例逻辑在同一张表中。因此,如果您组合成一个查询,您将通过可能比 UNION 更快的表。如果您在 AND 逻辑中添加一些 (),则可以执行此操作。你可以试试这个风格,看看它是否有效?

-- 组合代码样机

SELECT distinct order_no,status,status_cd,
  CASE when order_qty - fulfilled_qty > 0 then 'inventory-unavailable' END
  FROM t1 a, t2 b
 WHERE t1.PK = t2.FK (Add...)
   AND a.inventory_stockout='TRUE'
   AND a.flag_column='TRUE' 
   AND (status in '(fulfilled','pending' OR (AND a.flag_column='TRUE' 
        AND a.subscription_enabled='TRUE'))
GROUP BY order_no,status,status_cd;

【讨论】:

    【解决方案3】:

    即使你知道 order_qty 来自哪个表,因为你已经为你的两个表命名了 ab,最好始终使用别名,以表达你的意思。

    如果它们确实是字符串编码的布尔值,那么也有看起来像布尔值 inventory_stockoutflag_column 的东西是糟糕的性能。

    DISTINCT 也是一个 GROUP BY,但如果你有 DISTINCT,你不需要声明 GROUP BY 阶段,因为所有变量都被考虑在内。同样作为雪花笔记,this_should_have_a_name 没有在 GROUP BY 中命名,但它也不需要,因为它是 GROUP BY 中的一组事物的派生值。

    我假设您希望将结果集结合在一起,您可以像 littlefoot 所指出的那样 UNION 他们,但这将在两者之间运行,这是我假设您想要的。如果您知道两个结果集中有零个重复项,那么UNION ALL 会告诉数据库将结果连接在一起,这样会快得多。

    接下来你可以做一个 CTE 和 sub 选择公共部分到一个块中,然后 UNION 子结果如下:

    WITH cte AS (
        SELECT DISTINCT 
            order_no, 
            status,
            status_cd,
            IFF( order_qty - fulfilled_qty > 0, 'inventory-unavailable', NULL) AS this_should_have_a_name,
            a.subscription_enabled
        FROM t1 AS a, t2 AS b
        WHERE a.inventory_stockout = 'TRUE'
            AND a.flag_column = 'TRUE' 
    )
    SELECT order_no, status, status_cd, this_should_have_a_name
    FROM cte
    WHERE status in '(fulfilled','pending')
    
    UNION 
    
    SELECT order_no, status, status_cd, this_should_have_a_name
    FROM cte
    WHERE subscription_enabled='TRUE'
    ;
    

    现在我们看到它是这样写的,我们可以在 CTE 中放一个 OR

    WITH cte AS (
        SELECT DISTINCT 
            order_no, 
            status,
            status_cd,
            IFF( order_qty - fulfilled_qty > 0, 'inventory-unavailable', NULL) AS this_should_have_a_name,
            a.subscription_enabled
        FROM t1 AS a, t2 AS b
        WHERE a.inventory_stockout = 'TRUE'
            AND a.flag_column = 'TRUE' 
    )
    SELECT order_no, status, status_cd, this_should_have_a_name
    FROM cte
    WHERE ( status in '(fulfilled','pending')
        OR  subscription_enabled='TRUE' )
    ;
    

    或没有 CTE

    SELECT DISTINCT 
            order_no, 
            status,
            status_cd,
            IFF( order_qty - fulfilled_qty > 0, 'inventory-unavailable', NULL) AS this_should_have_a_name
        FROM t1 AS a, t2 AS b
        WHERE a.inventory_stockout = 'TRUE'
            AND a.flag_column = 'TRUE' 
            AND ( status in '(fulfilled','pending') 
                OR a.subscription_enabled='TRUE' )
    ;
    

    OR 的速度可能会慢一些,现在逻辑被合并了,你可以将 UNION ALL 所需的逻辑视为

    SELECT order_no, status, status_cd, this_should_have_a_name
    FROM cte
    WHERE status in '(fulfilled','pending')
        AND subscription_enabled != 'TRUE'
    
    UNION ALL 
    
    SELECT order_no, status, status_cd, this_should_have_a_name
    FROM cte
    WHERE subscription_enabled = 'TRUE'
    

    【讨论】:

    • 感谢您的帮助:)
    猜你喜欢
    • 2010-10-08
    • 1970-01-01
    • 2012-01-28
    • 2016-01-06
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多