【问题标题】:condense SQL in mySQL在 mySQL 中压缩 SQL
【发布时间】:2009-06-11 09:00:45
【问题描述】:

如何在 MySQL 中简化这段代码?

SELECT name,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 0, price, '')) AS date1,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 1, price, '')) AS date2,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 2, price, '')) AS date3,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 3, price, '')) AS date4,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 4, price, '')) AS date5,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 5, price, '')) AS date6,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 6, price, '')) AS date7,
AVG(price),SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name

所以计算的日期数是动态的?

【问题讨论】:

  • 我认为如果您告诉我们您想要的结果是什么,这个问题会更容易回答。从一开始,这个查询看起来就是个坏主意。

标签: sql mysql refactoring complexity-theory


【解决方案1】:

最好的方法可能是将其拆分为两个查询,一个用于加载平均价格和每人价格的总和:

SELECT
  AVG(price), SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name;

第二个是你想知道的最大值:

SELECT
  MAX(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name, to_days(thedate) - to_days('2009-06-13');

如果您真的希望所有列都在同一个查询中,请为第一个查询使用子查询(在大型数据库上可能效率不高)

SELECT
  MAX(price),
  AVG(price),
  SUM(price)
FROM `personals`
LEFT JOIN (
  SELECT
    AVG(price), SUM(price), name
  FROM `personals`
  WHERE personal_id = '1234' -- # this line is optional
  GROUP BY name
) totals
ON totals.name = personals.name
WHERE personal_id = '1234'
GROUP BY name, to_days(thedate) - to_days('2009-06-13');

【讨论】:

    【解决方案2】:

    您无法动态更改列数,但您可以非常轻松地为每个日期获取单独的行:

    SELECT to_days(thedate) - to_days('2009-06-13') as interval,
       max(price) FROM `personals`
    WHERE personal_id = '1234'
    GROUP BY name, thedate
    

    你需要做一个单独的查询来获取平均数据:

    SELECT name,
       AVG(price),SUM(price)
    FROM `personals`
    WHERE personal_id = '1234'
    GROUP BY name
    

    【讨论】:

      【解决方案3】:

      如果我对你的理解正确,那么我认为你不能做你想做的事:SQL 不能那样工作。如果您的查询正在从另一个程序中使用,并且您知道您感兴趣的天数集,那么您可以在提交之前将其构建为字符串。如果您想要所有可能的天数并且必须有一个 SQL 查询,那么我想 UNION 会这样做(尽管我更喜欢两个查询):

      SELECT
        name
      , to_days(thedate) - to_days('2009-06-13') AS num_days
      , MAX(price) As max_price
      , NULL AS avg_price
      , NULL AS sum_price
      FROM `personals`
      WHERE personal_id = '1234'
      GROUP BY
        name
      , to_days(thedate) - to_days('2009-06-13') 
      UNION ALL
      SELECT
        name
      , NULL
      , NULL
      , AVG(price)
      , SUM(price)
      FROM `personals`
      WHERE personal_id = '1234'
      GROUP BY name
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-14
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多