DB2SQL—根据填充的字段从多个可能值中获取单个值

k2arahey  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(258)

我有两张table;产品和价格
价格对一个产品有3个可能的定价级别,所有产品默认有一个级别1的价格;
1=样式
2=样式和颜色
3=款式、颜色和尺寸
prices表如下所示(level列只是为了演示,为了更容易理解,它在实际的表中不存在);

style | colour | size | price  | level
--------------------------------------
1111  |        |      | 100.00 | 1
1111  | BLUE   |      | 95.00  | 2
1111  | RED    | L    | 50.00  | 3
2222  |        |      | 88.00  | 1
2222  | GREY   |      | 66.00  | 2
2222  | WHITE  | M    | 27.00  | 3

我想查询产品表,添加一个价格栏,如下所示(同样是水平栏,仅供演示);

Style | Colour | Size | Price  | Level
--------------------------------------
1111  | BLACK  | S    | 100.00 | 1
1111  | BLUE   | S    | 95.00  | 2
1111  | RED    | L    | 50.00  | 3
2222  | BLACK  | S    | 88.00  | 1
2222  | GREY   | S    | 66.00  | 2
2222  | WHITE  | M    | 27.00  | 3

我能想到的最好的方法是在左外连接中将级别作为单独的表,并使用“is not null”来确定从级别3到级别1的价格;

SELECT T1.STYLE, T1.COLOUR, T1.SIZE,
       MIN(CASE WHEN L3.PRICE IS NOT NULL THEN L3.PRICE
                WHEN L2.PRICE IS NOT NULL THEN L2.PRICE
                WHEN L1.PRICE IS NOT NULL THEN L1.PRICE)
  FROM PRODUCTS T1
LEFT OUTER JOIN PRICES L1 ON (L1.STYLE, L1.COLOUR, L1.SIZE) = (T1.STYLE, ' ', ' ')
LEFT OUTER JOIN PRICES L2 ON (L2.STYLE, L2.COLOUR, L2.SIZE) = (T1.STYLE, T1.COLOUR, ' ')
LEFT OUTER JOIN PRICES L3 ON (L3.STYLE, L3.COLOUR, L3.SIZE) = (T1.STYLE, T1.COLOUR, T1.SIZE)
GROUP BY T1.STYLE, T1.COLOUR, T1.SIZE

虽然这样做效果很差,但由于现实世界中有许多更多的级别/标准,因此声明过大。有更好的方法吗?

uqcuzwp8

uqcuzwp81#

试试这个:

WITH 
  PRODUCT (style, colour, size) AS
(
VALUES
  (1111, 'BLACK', 'S')
, (1111, 'BLUE' , 'S')
, (1111, 'RED ' , 'L')
, (2222, 'BLACK', 'S')
, (2222, 'GREY' , 'S')
, (2222, 'WHITE', 'M')
)
, PRICES (style, colour, size, price) AS
(
VALUES
  (1111, '    ' , ' ', 100.00)
, (1111, 'BLUE' , ' ',  95.00)
, (1111, 'RED ' , 'L',  50.00)
, (2222, '    ' , ' ',  88.00)
, (2222, 'GREY' , ' ',  66.00)
, (2222, 'WHITE', 'M',  27.00)
)
SELECT STYLE, COLOUR, SIZE, PRICE
FROM
(
SELECT T.*, P.PRICE
, ROWNUMBER() OVER (PARTITION BY T.STYLE, T.COLOUR, T.SIZE ORDER BY  
  CASE 
    WHEN T.COLOUR = P.COLOUR AND T.SIZE = P.SIZE THEN 3
    WHEN T.COLOUR = P.COLOUR AND P.SIZE = '' THEN 2
    WHEN P.COLOUR = '' AND P.SIZE = '' THEN 1
    ELSE 0
  END DESC)
  AS ORD
FROM PRODUCT T
LEFT JOIN PRICES P ON P.STYLE = T.STYLE
)
WHERE ORD = 1;

只有一个左连接。”“最佳拟合”枚举 ROWNUMBER . 把这看作一个迭代过程。
如果你加入 PRODUCTPRICES 只是路过 STYLE 你可能会从 PRICES 对于中的每条记录 PRODUCT (实际上,本例中有3条记录)。对于不同的产品记录,这样的行数可能不同。
现在你只能选择其中一个,我称之为“最适合”。每一行都有一个附加列,其值等于 LEVEL 列值。如果两个表中的另外两列相等,则其值为3。要是…就好了 COLOUR 是平等的 PRICES.SIZE 如果是空的(似乎,我们可以将其视为具有相应颜色和任何大小的行),则其值为2。如果没有其他列相等 PRICES.COLOUR & PRICES.SIZE 如果是空的(价格为任何颜色和大小的这种风格),那么它有价值1。对于某些产品记录(如果没有),您可能会得到唯一的level=0记录 PRICES.COLOUR='' & PRICES.SIZE='' 以及 PRICES.COLOUR=PRODUCT.COLOUR & PRICES.SIZE='' ,但有些款式有不同颜色和尺寸的唱片)-最坏的情况是,这种款式的一些任意价格会被收取。
现在您必须为每个产品记录选择一个这样的记录。我们使用 ROWNUMBER 以前计算的级别上的函数。此函数返回最高级别的1。因此,如果有level=3记录(两个额外的列值相等),那么它得到ord=1。如果没有level=3记录,level=2记录得到ord=1,依此类推。

相关问题