我正在加入2个表,例如
PRODUCTS (PRODUCT_ID, NAME)
和
PRICE_LEVELS (PRODUCT_ID, PRICE, PRICE_LVL_NAME )
(ofc。它简化了,有几个连接)。
在PRICE_LEVELS
表中,我有一些价格级别名称的可能性,让我们说" DEFAULT "和LEVEL1,所以我们得到了类似的东西:
PRODUCT_ID | PRICE | PRICE_LVL_NAME
1 | 100 | _DEFAULT_
1 | 50 | LEVEL1
2 | 130 | _DEFAULT_
两个表都在视图中连接。
我需要的是获得价格,但只需要一次 - 我的意思是如果定义了LEVEL1,选择那个,否则选择DEFAULT。
与此同时,我使用了GROUP BY,似乎工作正常,但我不知道为什么(ofc。我已经使用了大量的测试数据而且它总是有效,但不确定,它是如何可靠的。)
让我们说我们的观点(合并两个表格)的名称为V_PRODUCTS,因此我正在运行查询:
SELECT *
FROM `V_PRODUCTS`
WHERE (PRICE_LVL_NAME = '_DEFAULT_' OR PRICE_LVL_NAME = 'LEVEL1')
GROUP BY `PRODUCT_ID `;
所以问题是:
为什么上面的查询有效? GROUP BY总是选择LEVEL1,如果可用,则选择DEFAULT。这正是我的需要,但需要理解为什么它会以这种方式工作。
有没有办法在SQL中更明确地做到这一点?
更新:可以有无限数量的可能级别
答案 0 :(得分:0)
Q1:它不可靠,它可能基于内部存储,可能随时发生变化。
Q2:使用外部联接加入表格两次并使用COALESCE返回最佳匹配:
SELECT ..., COALESCE(pl1.PRICE, pl2.PRICE)
FROM `V_PRODUCTS` as p
LEFT JOIN PRICE_LEVELS as pl1
ON p.PRODUCT_ID = pl1.PRODUCT_ID
and PRICE_LVL_NAME = 'LEVEL1')
LEFT JOIN PRICE_LEVELS as ply
ON p.PRODUCT_ID = pl2.PRODUCT_ID
and PRICE_LVL_NAME = '_DEFAULT_'
答案 1 :(得分:0)
我现在没有MySQL可以玩,但是你应该只需要替换这个MSSQL的IS NULL部分,以使它能够工作。
如果您在级别中不需要AlphaNum,或者可以添加一个INT字段,其中0是默认值,然后是1,依此类推,您可以将级别连接到自身以获得最大可用级别以加入到产品表。
SELECT PRODUCTS.*, PriceLvl.*
FROM [PRODUCTS] LEFT JOIN
(SELECT p1.*
FROM PRICE_LEVELS p1
LEFT JOIN PRICE_LEVELS p2 ON
(p1.PRODUCT_ID = p2.PRODUCT_ID
AND p2.PRICE_LVL > p1.PRICE_LVL)
WHERE p2.PRICE_LVL IS NULL) PriceLvl
ON PRODUCTS.PRODUCT_ID = PriceLvl.PRODUCT_ID
这需要
PRODUCT_ID NAME
1 Tshirts
2 Pants
和
PRODUCT_ID PRICE PRICE_LVL
1 10.00 0
1 15.00 1
2 40.00 0
1 20.00 2
并给出
PRODUCT_ID NAME PRODUCT_ID PRICE PRICE_LVL
1 Tshirts 1 20.00 2
2 Pants 2 40.00 0
答案 2 :(得分:0)
我为每个级别分配一个数值,默认为零,并将其存储在同一个表中。
Job.JobLocations
答案 3 :(得分:0)
WHERE price_level IN ('_DEFAULT_', 'mylevel')
ORDER BY
price_level = '_DEFAULT_'
LIMIT 1
WHERE
将获取1或2行。
price_level = '_DEFAULT_'
默认为1,否则在0之前排序为0. 0,因此,如果存在'mylevel',它将首先出现。
LIMIT 1
表示选择第一行(或唯一一行)。