【问题标题】:Is there a way to simplify this following mysql query?有没有办法简化以下 mysql 查询?
【发布时间】:2011-02-26 00:27:01
【问题描述】:

我想出了以下查询来返回产品定价数据。这个查询工作正常,但我想知道是否有办法简化/优化它?

查询会提取有关每个产品的产品和定价详细信息的信息。如果没有特定产品的定价详细信息 (p_p.pl_id = 2),请加入另一个包含定价详细信息的查询 (p_p.pl_id = 1)。最后按 id 对所有产品进行分组以获得不同的行。

使用的表格: 产品 - 有关产品的一些详细信息,例如名称、描述等。 product_pricing (p_p) - 包含每个产品的定价详情。一种产品可能有多个记录,因为产品价格因订购数量而异

SELECT * FROM (
(
SELECT `products`.*, 
GROUP_CONCAT(p_p.`qty_range` SEPARATOR '|') AS qty_range, 
GROUP_CONCAT(CAST(p_p.`p_price` AS CHAR) SEPARATOR '|') AS price 
FROM `products`
LEFT JOIN `prod_pricing` AS p_p ON p_p.`prod_id` = `products`.`prod_id` 
WHERE `products`.`account_id` = 2
AND p_p.`pl_id` = 2
GROUP BY `products`.`prod_id`
) 
UNION
(
SELECT `products`.*, 
GROUP_CONCAT(p_p.`qty_range` SEPARATOR '|') AS qty_range, 
GROUP_CONCAT(CAST(p_p.`p_price` AS CHAR) SEPARATOR '|') AS price 
FROM `products`
LEFT JOIN `prod_pricing` AS p_p ON p_p.`prod_id` = `products`.`prod_id` 
WHERE `products`.`account_id` = 2
AND p_p.`pl_id` = 1
GROUP BY `products`.`prod_id`
)) AS list
GROUP BY list.`prod_id`

【问题讨论】:

  • 使用存储过程(假设您的 Mysql 版本正确)?
  • 您不会因为加入 PROD_PRICING 而获得不同的记录。看起来您想要 pl_id 2,如果产品没有 2 条记录,则为 1...
  • OMG Ponies:因为我将临时表 'list' 按 'prod_id' 分组,所以我得到了不同的记录,但我知道这不是一个好习惯

标签: mysql sql query-optimization


【解决方案1】:

已编辑:我想我现在明白你的意思了,试试看:

SELECT t.col1, t.col2,  --[more columns from products table]
IF (t.price2 IS NULL, t.price1, t.price2) AS price,
IF (t.price2 IS NULL, t.qty_range1, t.qty_range2) AS qty_range
FROM
    (
    SELECT p.col1, p.col2 , --[more columns from products table]
    GROUP_CONCAT(p_p1.qty_range SEPARATOR '|') AS qty_range1, 
    GROUP_CONCAT(CAST(p_p1.p_price AS CHAR) SEPARATOR '|') AS price1,
    GROUP_CONCAT(p_p2.qty_range SEPARATOR '|') AS qty_range2,
    GROUP_CONCAT(CAST(p_p2.p_price AS CHAR) SEPARATOR '|') AS price2 
    FROM products p
    LEFT JOIN prod_pricing AS p_p1 ON p_p1.prod_id = p.prod_id AND p_p1.pl_id = 1
    LEFT JOIN prod_pricing AS p_p2 ON p_p2.prod_id = p.prod_id AND p_p2.`pl_id` = 2
    GROUP BY p.prod_id) AS t
Having price IS NOT NULL

【讨论】:

  • 我已经试过了。此查询将获取 pl.id = "1" 和 "2" 的定价详细信息。我想得到的是,如果 pl.id = 2 没有产品定价,那么获取 pl.id = 1 的定价
  • 这个查询很有意义,但仍然缺少一些东西。对于同时定价为 pl_id =1 和 2 的产品,我获得组合定价,而不是仅获得 pl_id = 2 的定价
  • @marcin_koss:你确定吗?如果两个连接都匹配,则临时表 (t) 将在 price1、price2、qty_range1 和 qty_range2 列中包含数据 - 但最终结果应该只有来自 price 2 的数据,因为 IF (t.price2 IS NULL, t.price1, t.price2) AS price 和来自 qty_range2 的数据因为IF (t.price2 IS NULL, t.qty_range1, t.qty_range2) AS qty_range
【解决方案2】:

由于两个 UNION 几乎相同,也许您可​​以查看CASE

你可以有

WHERE `products`.`account_id` = 2
AND `products`.`prod_id`
AND CASE x
    WHEN y THEN
      p_p.`pl_id` = 2
    ELSE
      p_p.`pl_id` = 1

虽然尚不清楚您在哪里/如何确定是否有定价细节。但是,无论哪一列确定了 x 的值,它的值都在 y 中。

【讨论】:

  • 如果需要,CASE 条件可以是一个 SELECT 语句。
  • 选择 products 。 * , GROUP_CONCAT( p_p.qty_range SEPARATOR '|' ) AS qty_range, GROUP_CONCAT( CAST( p_p.p_price AS CHAR ) SEPARATOR '|' ) AS 价格来自products LEFT JOIN prod_pricing AS p_p ON p_p. prod_id = products.prod_id WHERE products.account_id =2 AND CASE p.pp_product_id WHEN '' THEN p_p.pl_id = 2 否则 p_p.pl_id = 1查询,但我收到错误。
【解决方案3】:

好吧,我终于想通了。 我创建了两个临时表 t1,t2,它们反映了 pl_id = 1 和 2 的数据。接下来,我将这些表加入到 products 表中,并使用 IF 条件返回了定价从 pl_id = 2 和 pl_id =1 的产品,仅当定价为 pl_id = 2不存在。 感谢大家的帮助!

这是查询

选择 p.*, IF(t2.pl_id IS NULL,t1.qty_range,t2.qty_range) 作为 qty_range, IF(t2.pl_id IS NULL,t1.price,t2.price) AS 价格 FROM 产品 AS p 左连接 ( 选择 p_p.prod_id, GROUP_CONCAT(p_p.qty_range SEPARATOR '|') AS qty_range, GROUP_CONCAT(CAST(p_p.p_price AS CHAR) SEPARATOR '|') AS 价格 FROM prod_pricing AS p_p WHERE p_p.pl_id = 1 按 p_p.prod_id 分组 ) AS t1 ON t1.prod_id = p.prod_id 左连接 ( 选择 p_p.prod_id,p_p.pl_id, GROUP_CONCAT(p_p.qty_range SEPARATOR '|') AS qty_range, GROUP_CONCAT(CAST(p_p.p_price AS CHAR) SEPARATOR '|') AS 价格 FROM prod_pricing AS p_p WHERE p_p.pl_id = 1 按 p_p.prod_id 分组 ) AS t2 ON t2.prod_id = p.prod_id 其中 p.account_id = 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多