【问题标题】:How can i check if the value exists and return different values depending on the answer?如何检查该值是否存在并根据答案返回不同的值?
【发布时间】:2018-09-06 05:25:27
【问题描述】:

首先让我解释一下我现在使用的查询。

作为示例,此查询返回值“357 kg”:

SELECT TOP 1 
     CONCAT(POCI.Value,' kg')
FROM 
     ProductionOrder PO
          LEFT JOIN Product P ON P.ProductionOrderId = PO.ProductionOrderId
          LEFT JOIN ProductionOrderConfiguration POC ON POC.ProductionOrderConfigurationId = PO.ProductionOrderConfigurationId 
          LEFT JOIN ProductionOrderConfigurationItem POCI ON POCI.ProductionOrderConfigurationId = POC.ProductionOrderConfigurationId
WHERE 
     P.ProductId = #ProductId# AND POCI.Name = 'C_VIKTA'

问题是有时记录中不存在 POCI.Name (C_VIKTA),因此它的值 (POCI.Value) 不会被返回。 所以我想让下面的逻辑起作用,我知道它可以用 CASE 和 EXISTS 来解决,但我就是不让它起作用..

我想要的结果是如果 POCI.Value 存在返回 CONCAT(POCI.Value,'kg') ELSE 返回'N/A'。有人知道如何解决这个问题吗?

如果您需要了解其他信息以帮助我,请告诉我!

BR,

米克

【问题讨论】:

  • Order by在使用Top时起着重要作用:)
  • @LONG 好点子,虽然在这种情况下可能知道它会是相同的重复值并且顺序无关紧要,但我有时会遇到这种情况
  • @AnthonyHancock,是的,也许 op 有一个聚集索引,所以每次他运行 xD 时结果都是一致的
  • Order by 没关系,它只能是 1 条记录,TOP 1 在那里,因为它是在某个时候从另一个查询中复制的,但感谢您的提示 :)
  • @LONG 您能否向我指出一个参考资料,该参考资料解释了在某处具有聚集索引的四个联接表的结果的保证 顺序?我的微弱理解是,如果没有order by 子句,就不能保证顺序不会随着新的索引统计信息、软件补丁、额外的处理器内核……而改变。 (有关在测试中始终如一的故事:The "Bug" Heard 'Round the World。)

标签: sql-server tsql select case exists


【解决方案1】:

这个WHERE POCI.Name = 'C_VIKTA' 打破了左连接
所以把它移到左连接或者让它们都是常规连接

如果只返回一行,则删除顶部

+ 的行为与 concat 不同

SELECT ISNULL(POCI.Value +' kg','N\A')
FROM ProductionOrder PO
JOIN Product P 
       ON P.ProductionOrderId = PO.ProductionOrderId
JOIN ProductionOrderConfiguration POC 
       ON POC.ProductionOrderConfigurationId  = PO.ProductionOrderConfigurationId 
JOIN ProductionOrderConfigurationItem POCI 
       ON POCI.ProductionOrderConfigurationId = POC.ProductionOrderConfigurationId           
WHERE POCI.Name = 'C_VIKTA' 
  AND P.ProductId = #ProductId# 

为什么需要ProductionOrderConfiguration POC

SELECT ISNULL(POCI.Value +' kg','N\A')
    FROM ProductionOrder PO
    JOIN Product P 
           ON P.ProductionOrderId = PO.ProductionOrderId
    JOIN ProductionOrderConfigurationItem POCI 
           ON POCI.ProductionOrderConfigurationId = PO.ProductionOrderConfigurationId           
    WHERE POCI.Name = 'C_VIKTA' 
      AND P.ProductId = #ProductId#

【讨论】:

    【解决方案2】:

    我认为最简单的方法是删除处理空值的 CONCAT,然后依赖为空值。因此,您的单个选择列将是

    SELECT TOP 1 ISNULL(POCI.Value+' kg','N\A')
    

    这样,如果 POCI.Value 为空,则第一个参数为空,因此返回 'N\A'

    【讨论】:

    • 正如@Stivan 在他的回答中提到的那样,您肯定必须将名称检查移出 where 子句,否则当名称不匹配时您将不会返回任何内容。
    【解决方案3】:

    我建议你将 AND POCI.Name = 'C_VIKTA' 从 where 子句移动到你的左连接,如下所示

    SELECT TOP 1 
         case when POCI.Value is not null then CONCAT(POCI.Value,' kg') else '' end
    FROM 
         ProductionOrder PO
              LEFT JOIN Product P ON P.ProductionOrderId = PO.ProductionOrderId
              LEFT JOIN ProductionOrderConfiguration POC ON POC.ProductionOrderConfigurationId = PO.ProductionOrderConfigurationId 
              LEFT JOIN ProductionOrderConfigurationItem POCI ON POCI.ProductionOrderConfigurationId = POC.ProductionOrderConfigurationId AND POCI.Name = 'C_VIKTA'
    WHERE 
         P.ProductId = #ProductId#
    

    【讨论】:

    • 谢谢 Stivan,效果很好。正是我想要的!干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2013-02-15
    • 2021-11-01
    相关资源
    最近更新 更多