我有一个非常具体的问题,并且我一直在努力解决这个问题,但是没有运气。
基本上,我要实现的目标是基于货币值从定价表“ product_line_price”中获得最低价格。诀窍是product_line_price表并不总是包含特定货币的值,在这种情况下,它必须默认为选择默认的“ AUD”货币。该表还包含具有不同定价方案的每种产品的多个记录,但是对于我要查询的特定货币,我只对它们中最便宜的(最低价格)感兴趣。
最终目标用于产品的“多面搜索”,用户可以选择价格范围以列出该特定范围内的产品。
这是我尝试过的整体查询,我认为这是最接近的尝试:
SELECT *
FROM product_line
LEFT JOIN
(
SELECT idproduct_line,
idprice_group,
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price.idproduct_line) THEN Min(price)
ELSE Min(price)*0.5098
END AS userprice
FROM product_line_price
WHERE !deleted
AND
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price.idproduct_line) THEN currency_code = 'GBP'
ELSE currency_code = 'AUD'
END
GROUP BY idproduct_line
ORDER BY product_line_price.idproduct_line ASC) AS product_line_price
ON product_line.idproduct_line = product_line_price.idproduct_line
WHERE !product_line.deleted
AND product_line.idproduct_line_status = 1
AND product_line.idproduct_line IN
(
SELECT `idproduct_line`
from `product_line_has_product_category`
where `idproduct_category` = '103')
AND ((
product_line_price.idprice_group IN
(
SELECT `idprice_group`
FROM `price_group`
WHERE !`deleted`
AND `PUBLIC`
AND `active`))
AND (
userprice <= 250))
ORDER BY product_line.idproduct_line ASC
我遇到麻烦的子查询就是这个:
SELECT idproduct_line,
idprice_group,
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price.idproduct_line) THEN Min(price)
ELSE Min(price)*0.5098
END AS userprice
FROM product_line_price
WHERE !deleted
AND
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price.idproduct_line) THEN currency_code = 'GBP'
ELSE currency_code = 'AUD'
END
GROUP BY idproduct_line
ORDER BY product_line_price.idproduct_line ASC
因此,我需要能够检索GBP货币(如果存在)的值,否则默认为AUD货币(并应用货币转换)。这里的一些数字经过硬编码以进行测试,稍后将通过变量提供。
我有一种感觉,就是使用上述子查询,EXISTS子查询不能正确使用idproduct_line值,因为当我运行它时,即使该表中有很多记录没有GBP结果,我也只能得到GBP结果。我正在谈论的子查询就是这个:
SELECT currency_code
FROM product_line_price
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price.idproduct_line
谁能看到我要去哪里错了?我感觉自己是如此接近,但是该子查询中的某些内容只是错误的,而SQL并不是我的最佳选择。
编辑1:
我主要关心的是包含EXISTS子句的子查询,我知道它的其余部分都可以正常工作,并且仅出于上下文目的提供了整个查询。
您可以从以下链接下载相关表的转储和一些示例数据。样本数据包含3种产品的定价,一种仅具有AUD定价,一种具有AUD和GBP定价,以及一种具有多种货币的定价。
https://www.dropbox.com/s/h1i23f5ac2jmrvn/product_line_price.sql?dl=0
我针对此数据运行的查询是:
SELECT idproduct_line,
idprice_group,
currency_code,
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price_2
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price_2.idproduct_line AND !deleted) THEN Min(price)
ELSE Min(price)*0.5098
END AS userprice
FROM product_line_price_2
WHERE !deleted
AND
CASE
WHEN EXISTS
(
SELECT currency_code
FROM product_line_price_2
WHERE currency_code = 'GBP'
AND idproduct_line = product_line_price_2.idproduct_line AND !deleted) THEN currency_code = 'GBP'
ELSE currency_code = 'AUD'
END
GROUP BY idproduct_line
ORDER BY product_line_price_2.idproduct_line ASC
我的预期输出是3条记录,其中2条记录的GBP定价显示最小值,而1条记录的AUD定价显示最小值,转换为GBP(通过查询中的“ * 0.5098”)。
我看到的实际输出只有2条以GBP定价的记录,因此它忽略了AUD定价。
最佳答案
因此,经过长期的努力和工作同事的帮助,我们采取了另一种方法,并找到了解决此问题的方法。
SELECT product_line.idproduct_line,
Min(local_price.price) local_userprice,
Min(fallback_price.price) fallback_userprice
FROM product_line
INNER JOIN product_line_has_product_category
ON product_line.idproduct_line =
product_line_has_product_category.idproduct_line
AND 103 = product_line_has_product_category.idproduct_category
LEFT JOIN (product_line_price local_price
INNER JOIN price_group local_price_group
ON local_price.idprice_group =
local_price_group.idprice_group
AND ! local_price_group.deleted
AND local_price_group.PUBLIC
AND local_price_group.active)
ON product_line.idproduct_line = local_price.idproduct_line
AND 'GBP' = local_price.currency_code
LEFT JOIN (product_line_price fallback_price
INNER JOIN price_group fallback_price_group
ON fallback_price.idprice_group =
fallback_price_group.idprice_group
AND ! fallback_price_group.deleted
AND fallback_price_group.PUBLIC
AND fallback_price_group.active)
ON product_line.idproduct_line = fallback_price.idproduct_line
AND 'AUD' = fallback_price.currency_code
WHERE ! product_line.deleted
AND product_line.idproduct_line_status = 1
GROUP BY product_line.idproduct_line
HAVING ( local_userprice IS NULL
AND fallback_userprice <= 250 )
OR ( local_userprice <= 250 )
ORDER BY product_line.idproduct_line ASC
使用联接,交叉引用GBP和AUD的值(这在同一行中为价格和货币提供了2列)..然后我们可以使用HAVING子句比较每列,结果是成功的!