【问题标题】:SQL Join with case statementSQL Join with case 语句
【发布时间】:2024-01-14 18:41:01
【问题描述】:

我有这五张桌子

order_type(id,name)
order_stage_install(id,name)
order_stage_remove(id,name)
order_stage_redo(id,name)
orders(id,typeid,stageid)

我需要在这些条件下动态加入订单表

    if order.typeid=1 
then join order_stage_install on order.stageid=order_stage_install.id
    if order.typeid=2 
then join order_stage_remove on order.stageid=order_stage_remove.id

我试过了

    SELECT  *
FROM  orders o
            CASE 
            WHEN o.Type IN (1) THEN
             JOIN orders_stage os ON o.stageID=os.ID
            end

但它在“CASE”错误附近给了我不正确的语法 我对sql中的case语句和if语句进行了研究,但没有希望。任何帮助表示赞赏

【问题讨论】:

  • 您不能使用 case 表达式 有条件地连接不同的表。改为使用 LEFT JOIN。
  • 即使有一些语法允许您这样做(您可以尝试动态 sql),这意味着对于不同行中的 order.typeid 的不同值,您将有不同的列。这当然是不可能的。
  • 这是一个常见问题解答。请在考虑发布之前阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:*.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。
  • 你没有说你想做什么。提供无意义的代码不会传达您的想法。使用足够多的单词、句子和对部分示例的引用来清楚完整地表达你的意思。在给出业务关系(船)/关联或表(基础或查询结果)时,说明其中的一行根据其列值说明了业务情况。请在代码问题中给出minimal reproducible example--包括剪切、粘贴和可运行的最小代码以及以代码形式给出的最小代表性数据。对于包含 DBMS 和 DDL 的 SQL,包括约束、索引和表格初始化。

标签: sql sql-server join case


【解决方案1】:

您需要使用 LEFT JOIN 并使用 COALESCE 子句来处理来自表的 NULL 值。例如,如果 order_install 和 order_remove 都可以有 OrderDetailname 并且其中之一将根据 typeId 给出值。

你需要有COALESCE(order_install.OrderDetailName, order_remove.OrderDetailName) AS OrderDetailName


SELECT  o.*, -- COALESCE( You need to have COALESCE clause here to handle values coming from both tables
FROM  orders o
LEFT OUTER join order_stage_install on order.stageid=order_stage_install.id
AND o.typeId = 1
LEFT OUTER JOIN order_stage_remove  on order.stageid=order_stage_remove.id
AND o.typeId = 2

【讨论】:

    【解决方案2】:

    我知道一个人应该只回答一个问题。但在这种情况下,似乎最好先优化数据结构以避免 JOIN。

    数据结构似乎不是最优的,委婉地说。 这随后会导致复杂的 JOIN 策略和许多其他问题。

    请解释这三个 order_stage_* - 表包含哪些内容以及将为您做什么。

    我的猜测是您希望将这些订单存储在具有特定阶段的这三个表中。 但这需要在表订单上仅使用一个附加属性来完成,以防这些阶段是不相交的(= 总是不同,一个订单不可能有多个阶段)。

    【讨论】:

      【解决方案3】:

      正如@Venkataraman_R 提到的,他的解决方案解决了问题 这是完整的sql语句

      SELECT  
      COALESCE(osn.enum,osr.enum,osre.enum) as 'Current Stage',
      COALESCE(oen.enum,oer.enum,oere.enum) as 'Current Phase',ot.enum as 'Order Type',
      o.ID,scheduled_date as 'Scheduled'
        ,opened_date as 'Opened'
      FROM  orders o
      LEFT OUTER JOIN orders_types ot ON o.Type = ot.ID
      
      LEFT OUTER join orders_stage osn  on o.stageID=osn.ID
      AND o.Type = 1
      LEFT OUTER JOIN orders_stage_removal osr  on o.stageID=osr.ID
      AND o.Type = 2
      LEFT OUTER JOIN orders_stage_redo osre  on o.stageID=osre.ID
      AND o.Type = 3
      
      LEFT OUTER join orders_enum_install oen  on o.enumID=oen.ID
      AND o.Type = 1
      LEFT OUTER JOIN orders_enum_removal oer  on o.enumID=oer.ID
      AND o.Type = 2
      LEFT OUTER JOIN orders_enum_redo oere  on o.enumID=oere.ID
      AND o.Type = 3
      

      【讨论】: