【问题标题】:SELECT one column twice from same table with two WHERE conditions SQL SERVER使用两个 WHERE 条件从同一个表中选择一列两次 SQL SERVER
【发布时间】:2016-03-01 18:17:40
【问题描述】:

我试图找出最简单的方法,从同一个表中选择一个列两次,但在更大的查询中并排显示两个不同的 WHERE 条件(如下)。实现这一目标的最佳方法是什么?

USE PDX_SAP_USER 

GO 

SELECT          P.PLANT_CODE,
                P.STOCK_CATEGORY,
                P.MATERIAL,
                P.DISTRIBUTION_VERSION_CODE,
                P.PERIOD_CODE,
                P.REQUIREMENTS_DATE,
                P.PLANNED_QTY AS 'REM PLAN QTY',
                P.VERSION_IND_FLAG,
                P.SIZE_LITERAL,
                P.WITHDRAWN_QUANTITY,
                P.TECHNICAL_INDEX,
                P.PLANNED_QTY + P.WITHDRAWN_QUANTITY AS 'ORIGINAL FCST QTY'
 FROM           VW_PLANNED_REQMNTS_TXT P
 WHERE          P.PLANT_CODE IN ('6040','6041')
 AND            P.STOCK_CATEGORY IN ('A60385000','A60385003')
 AND            P.DISTRIBUTION_VERSION_CODE IN ('00','01','ZU','Z2')
 AND            P.REQUIREMENTS_DATE < GETDATE() - 59
 AND            P.PLANNED_QTY > 0 
 ORDER BY       P.PLANT_CODE,
                P.STOCK_CATEGORY,
                P.MATERIAL,
                P.REQUIREMENTS_DATE,
                P.TECHNICAL_INDEX

【问题讨论】:

  • OOPS - 我希望使用当前日期限制显示列 P.PLANNED_QTY,然后还显示它必须在将来进行比较的限制。
  • 可能会提供一些示例数据以及您希望输出的样子。
  • 感谢您的回复 - 所以现在这个查询会生成所有列,如下所示。我想准确地生成这个,但是使用另一个 P.PLANNED_QTY 来显示当 WHERE 更改为 > GETDATE() 时的值 - 用于未来的金额。
  • 哪一栏是> GETDATE()? P.REQUIREMENTS_DATE?你想要所有未来的行,还是最早的,还是最后的?
  • 谢谢保罗。我想按目前的样子投影列 P.PLANNED_QTY,它是整个查询的一部分,从今天开始根据 P.REQUIREMENTS_DATE 回顾 59 天,但如果可能,还添加同一列的投影,其中显示 P 的所有值.PLANNED_QTY 从今天开始由 MATERIAL 捆绑在一起。因此,它将显示 59 天前的计划数量和每种材料的计划数量。感谢所有的帮助。

标签: sql sql-server join


【解决方案1】:

根据情况,有几种不同的策略可以有条件地从查询中排除特定列数据。

如果一个是另一个的子集,您可以使用CASE 排除不需要的值

SELECT
   PS.ProductShipmnetId
   ,PS.ShipmentDate
   ,PS.ProductQty
   ,CASE 
      WHEN PS.ShipmentDate BETWEEN GETDATE() AND DATEADD(MONTH, 1, GETDATE()) 
         THEN PS.ProductQty 
    END AS ProductQtyThisMonth
FROM
   ProductShipment PS
WHERE
   PS.ShipmentDate > DATEADD(MONTH, -1, GETDATE())

如果 where 子句不重叠,那么 UNION ALL 可能是更好的选择。你也可以OR这两个条件一起为每个返回添加一个案例。

SELECT
   PS.ProductShipmnetId
   ,PS.ShipmentDate
   ,PS.ProductQty AS ProductQtyAncient
   ,NULL AS ProductQtyFuturistic
FROM
   ProductShipment PS
WHERE
   PS.ShipmentDate < DATEADD(YEAR, -1, GETDATE())
UNION ALL
SELECT
   PS.ProductShipmnetId
   ,PS.ShipmentDate
   ,NULL AS ProductQtyAncient
   ,PS.ProductQty AS ProductQtyFuturistic
FROM
   ProductShipment PS
WHERE
   PS.ShipmentDate > DATEADD(YEAR, 1, GETDATE())

我更常看到这些技术与聚合函数一起使用,你提到这是更大查询的一部分,所以我想确保你也知道这一点。

SELECT
   PS.ProductId
   ,SUM(CASE WHEN PS.ShipmentDate BETWEEN GETDATE() AND DATEADD(MONTH, 1, GETDATE())
           THEN PS.ProductQty END) AS ProductQtyThisMonth
   ,SUM(CASE WHEN PS.ShipmentDate BETWEEN DATEADD(MONTH, -1, GETDATE()) AND GETDATE()
           THEN PS.ProductQty END) AS ProductQtyLastMonth
FROM
   ProductShipment PS
WHERE
   PS.ShipmentDate BETWEEN DATEADD(MONTH, -1, GETDATE()) 
       AND DATEADD(MONTH, 1, GETDATE())
GROUP BY
   PS.ProductId

【讨论】:

  • 感谢您提出的所有这些想法,我认为 UNION 是我正在寻找的,因为它允许我运行基本相同的查询,但该子句不同。我唯一的问题是 - 它需要显示两个语句的所有列还是我只能显示某些列(例如仅来自 UNION 第二部分的 PLANNED_QTY)我将继续深入研究这一点,但感谢右侧的推动方向。
  • @user 对于联合,列签名需要在连接的查询之间匹配,但不一定必须相同。如果有没有意义的列,你可以用 NULL 或常量值替换它们。
【解决方案2】:

您可以将此“模板”用于选择连接:

SELECT * -- <your final query, use Q1.field and Q2.field>
FROM 
    (SELECT <query1> WHERE <condition1>) Q1
LEFT JOIN
    (SELECT <query2> WHERE <condition2>) Q2
-- add more joins if necessary
ON
    Q1.pk = Q2.pk

剩下的唯一部分是识别选择将加入的主键。

附:当然不一定只有LEFT JOIN,这正是你通常想要的。

【讨论】:

  • 谢谢,我认为这给了我另一个我从未想过的选择 - 非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多