【问题标题】:Use previous value in MySQL to compute the next field?使用 MySQL 中的先前值来计算下一个字段?
【发布时间】:2013-10-31 00:05:52
【问题描述】:

如何使用 MySQL 中的先前值来计算下一个值?我用我蹩脚的英语无法更清楚地解释我的意思(任何人都可以通过看到这篇文章的标题来理解我的问题吗?),所以让我用sn-p解释一下:


select
year_id,
sum(case when event_cd >= 20 then 1 else 0 end) as h,
sum(case when ab_fl = "T" then 1 else 0 end) as ab,
h/ab as ba
from events
group by year_id

在上面的sn-p中,当你运行查询时你会得到错误,因为events表中没有hab这样的列。但是,我想使用 hab,它们是在前面的 sum(case when ~) 语法中计算的。我记得有一些方法可以使它成为可能,但我不记得该怎么做,也不记得我说的那样,由于我的英语不好,我找不到任何相关的帖子来满足我的要求,尽管因为我确定这个问题已经在 SO 上发布了,即使您只是链接它而没有详细说明,它也很有帮助。

谢谢。

[更新]

感谢您的回答。我只是想使用以前的值来避免子查询,从而避免大量冗余输入,并使整个代码更具可读性。正如 Mosty Mostacho 所描述的,我已经使用了两种方法(子查询或编写整个语法两次以计算另一个值),如果这在 MySQL 中使用不可行或风险很大,我当然可以接受上面的这两种方法。很抱歉造成混乱。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    在 MySQL 中有 2 种方式(顺便说一句,我已经稍微简化了查询,但它仍然是合法的):

    选项 #1:展开变量

    SELECT
      year_id,
      SUM(event_cd >= 20) h,
      SUM(ab_fl = "T") ab,
      SUM(event_cd >= 20) / SUM(ab_fl = "T") ba
    FROM events
    GROUP BY year_id
    

    选项 #2:使用派生表

    SELECT year_id, h, ab, h / ab ba FROM (
        SELECT
          year_id,
          SUM(event_cd >= 20) h,
          SUM(ab_fl = "T") ab
        FROM events
        GROUP BY year_id
    ) s
    

    您可能会认为第二个会运行得更快,但事实并非如此。第一个最有可能运行得更快,因为它不需要派生表,只需一次即可解决问题。

    【讨论】:

    • 很抱歉给您带来了困惑,但我只想像我在原始帖子中所说的那样写出来。我知道这两个选项,并且已经多次使用它。但是,有了你和fancyPants 上面的回答,现在我不确定我在 MySQL 上读到了什么……不过还是谢谢你的回答。
    【解决方案2】:

    试试

    select * h/ab as ba from 
    (
    select
    year_id,
    sum(case when event_cd >= 20 then 1 else 0 end) as h,
    sum(case when ab_fl = "T" then 1 else 0 end) as ab,
    from events
    group by year_id)
    source
    

    【讨论】:

    • 对不起,我的意思是我只想在一个查询中写出来(没有子查询)。
    • select year_id, sum(case when event_cd >= 20 then 1 else 0 end) as h, sum(case when ab_fl = "T" then 1 else 0 end) as ab, sum(case when event_cd >= 20 then 1 else 0 end) / sum(case when ab_fl = "T" then 1 else 0 end) as ba from events group by year_id
    【解决方案3】:

    更新 正如@MostyMostacho 在下面的评论中解释的那样,这不是一种可取的技术,因为未定义用户变量的评估顺序。


    您可以使用 MySQL 变量编写查询,使用语法 @varname := 'value' 来存储总和,然后引用它。

    SELECT
      year_id
    , @h := SUM(CASE WHEN event_cd >= 20 THEN 1 ELSE 0 END) AS h
    , @ab := SUM(CASE WHEN ab_fl = "T" THEN 1 ELSE 0 END) AS ab
    , @h/@ab AS ba
    FROM events
    GROUP BY year_id
    

    【讨论】:

    • 根据MySQL documentationthe order of evaluation for expressions involving user variables is undefined。依赖它是有风险的。
    • 谢谢。但是,当我使用另一个group by 类别(例如group by year_id, bat_id)运行此查询时,它返回的每条记录都具有完全相同的值。那么如何使用多个组呢?
    • @MostyMostacho 谢谢,我已经更新了我的答案以反映这一点。 user2360798 抱歉,看来此方法不适合您。
    猜你喜欢
    • 2015-09-03
    • 2023-03-14
    • 2021-01-19
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多