【问题标题】:Reuse expression in SQL sentence在 SQL 语句中重用表达式
【发布时间】:2011-05-18 11:33:29
【问题描述】:

我正在使用 MySQL,我想简化一个有点复杂的 SQL 语句。

查询是这样的:

SELECT `provider`.*,`products`.`placement`,`price`.`price`+
   IFNULL((SELECT `price` FROM `price` WHERE `handle`=
     (SELECT `group` FROM `group_provider` WHERE `provider_id`=`provider`.`id`)),'0') AS `price`
FROM `provider` 
LEFT JOIN `products` ON `provider`.`id`=`products`.`web` 
LEFT JOIN `price` ON `price`.`handle`=`provider`.`id` 
WHERE `products`.`type`='$PRODUCT_TYPE'
  AND `price`.`price`+
   IFNULL((SELECT `price` FROM `price` WHERE `handle`=
     (SELECT `group` FROM `group_provider` WHERE `provider_id`=`provider`.`id`)),'0')>0

此查询运行良好,但问题是我有一个重复的项目,我不知道如何简化它。我说的重复项是:

  `price`.`price`+
   IFNULL((SELECT `price` FROM `price` WHERE `handle`=
     (SELECT `group` FROM `group_provider` WHERE `provider_id`=`provider`.`id`)),'0')

有什么简化的办法吗?谢谢

【问题讨论】:

  • 查看它不是一个选项,因为数据库正在使用 MyISAM。据我所知 MyISAM 不支持视图 :(

标签: mysql simplify


【解决方案1】:

Create a view 包含额外列的数据并查询此视图。创建视图后,查询变得非常简单:

SELECT *
FROM your_view
WHERE type = 42
AND price > 0

【讨论】:

    【解决方案2】:

    SELECTWHERE 子句之后进行评估,因此SELECT 中定义的列别名不能在WHERE 中使用。

    MySQL 的不同寻常之处在于它允许您在 having 子句中使用列别名,因此您可以重新编写查询以将谓词从 where 子句移动到 having 子句。

    或者,您可以使用以下定义创建视图或派生表

    SELECT `provider`.*          ,
           `products`.`placement`,
           `price`.`price`+ IFNULL(
           (SELECT `price`
           FROM    `price`
           WHERE   `handle`=
                   (SELECT `group`
                   FROM    `group_provider`
                   WHERE   `provider_id`=`provider`.`id`
                   )
           )
           ,'0')>0 AS `price`
    FROM   `provider`
           LEFT JOIN `products`
           ON     `provider`.`id`=`products`.`web`
           LEFT JOIN `price`
           ON     `price`.`handle`=`provider`.`id`
    

    并根据马克的回答在SELECT 中引用WHERE 子句中的列别名。我对 MySQL 查询优化器还不够熟悉,无法知道这两种方法中的任何一种是否会对性能产生影响。

    【讨论】:

      【解决方案3】:

      试试这个,应该可以的。

      首先,你应该创建视图

          CREATE VIEW `DB`.`view1` AS 
          SELECT `provider`.*, `products`.`placement`, `price`.`price`+ IFNULL((SELECT
          `price` FROM `price` WHERE `handle`= (SELECT `group` FROM `group_provider`
          WHERE `provider_id`=`provider`.`id`)),'0') AS `price`
          FROM `provider`
          LEFT JOIN `products` ON `provider`.`id`=`products`.`web`
          LEFT JOIN `price` ON `price`.`handle`=`provider`.`id`

      为该视图创建查询选择

          SELECT * FROM `view1` WHERE `price` > 0

      这只有在你使用 InnoDB 时才有效。

      【讨论】:

      • 恐怕这些表不是 InnoDB
      • 我想你应该在你的问题上提到它(MYISAM,我猜)
      猜你喜欢
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多