如果设置则检索特定值,否则检索一般值

时间:2017-11-17 11:17:59

标签: sql sql-server database

我必须编写一个查询,它将从表中导入一些数据。表结构如下:

  • 的Item_ID
  • 植物
  • 价格

我有第二张表

  • 的Item_ID
  • 植物

第二个表是一个键,我必须匹配第一个表中的行才能获得有效价格。然而,似乎很容易: 在第一个表中,列工厂可能确定特定工厂,或具有值“ALL”。我想要做的是检索给定工厂的价格(如果已设置),或者如果给定工厂没有行,则获得价值'ALL'的价格。换句话说:

If first.Plant = second.Plant
  return price
Else If first.Plant = 'ALL'
  return price
Else
  return NULL

我不能使用简单的ON first.Plant = second.Plant OR first.Plant = 'ALL',因为可能有两行:一行用于给定植物,第二行用于休息,值为'ALL'。在这种情况下,我只需要返回第一个价格。 E.g。

Item_ID  | Plant  | Price 
  2      |   M1   |  10,0
  2      |  All   |  12,0
  1      |  All   |  9,0

在这种情况下,Item_ID = 2且Plant = M1 唯一有效价格= 10,但是对于Item_ID = 2和Plant = M2 price = 12,对于任何Item_ID = 1 price = 9

我希望你在解释之后理解一些事情;)

1 个答案:

答案 0 :(得分:0)

使用ROW_Number和公用表表达式可以确保ROW_NUMBER按Item_ID和Plant进行分区并进行排序,如果有两行则“全部”为第二行。然后,您可以简单地选择行号= 1的行:

<强> 设置

CREATE TABLE #Price
(
    Item_ID int,
    Plant Varchar(20),
    Price Decimal(6,2)
)

CREATE TABLE #Plant
(
    Item_ID int,
    Plant VARCHAR(20)
)

INSERT INTO #Price
VALUES  (2,  'M1', 10.0),
        (2, 'All', 12.0),
        (1, 'All', 9.0)

INSERT INTO #Plant
VALUES (2,  'M1'),
        (2, 'M2'),
        (1, 'M1'),
        (1, 'M2')

以下是SQL Server&gt; = 2012

的查询
;WITH CTE
AS
(
    SELECT PL.Item_ID, PL.Plant, PR.PRice, ROW_NUMBER() OVER (PARTITION BY Pl.Item_ID, Pl.Plant ORDER BY IIF(PR.Plant = 'All', 1, 0)) AS RN
    FROM #Plant PL
    INNER JOIN #Price PR
        ON PL.Item_Id = PR.Item_Id AND  (PL.Plant = PR.Plant OR PR.Plant = 'ALL')
)
SELECT Item_Id, Plant, Price
FROM CTE
WHERE RN = 1

这是一个使用CASE的版本,适用于所有SQL Server&gt; = 2008 R2

;WITH CTE
AS
(
    SELECT PL.Item_ID, PL.Plant, PR.PRice, ROW_NUMBER() OVER (PARTITION BY Pl.Item_ID, Pl.Plant ORDER BY CASE WHEN PR.Plant = 'All' Then 1 Else 0 End) AS RN
    FROM #Plant PL
    INNER JOIN #Price PR
        ON PL.Item_Id = PR.Item_Id AND  (PL.Plant = PR.Plant OR PR.Plant = 'ALL')
)
SELECT Item_Id, Plant, Price
FROM CTE
WHERE RN = 1