我有一个非常具体的问题,并且我一直在努力解决这个问题,但是没有运气。

基本上,我要实现的目标是基于货币值从定价表“ 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子句比较每列,结果是成功的!

10-06 05:44