Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8257937
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T02:22:09+00:00 2026-06-08T02:22:09+00:00

According to the MySQL documentation: As a general rule, you should never assign a

  • 0

According to the MySQL documentation:

As a general rule, you should never assign a value to a user variable and read the value within the same statement. You might get
the results you expect, but this is not guaranteed.

http://dev.mysql.com/doc/refman/5.6/en/user-variables.html

However, in the book High Perfomance MySQL there are a couple of examples of using this tactic to improve query performance anyway.

Is the following an anti-pattern and if so is there a better way to write the query while maintaining good performance?

set @last = null;
select tick, count-@last as delta, @last:=count from measurement;

For clarification, my goal is to find the difference between this row and the last. My table has a primary key on tick which is a datetime column.

Update:

After trying Shlomi’s suggestion, I have reverted back to my original query. It turns out that using a case statement with aggregate functions produces unexpected behavior. See for example:

case when (@delta := (max(measurement.count) - @lastCount)) AND 0 then null
when (@lastCount := measurement.count) AND 0 then null
else @delta end

It appears that mysql evaluates the expressions that don’t contain aggregate functions on a first pass through the results, and then evaluates the aggregate expressions on a second (grouping) pass. It appears to evaluate the case expression during or after that second pass and use the precalculated values from the first pass in that evaluation. The result is that the third line @delta is always the initial value of @delta (because assignment didn’t happen until the grouping pass). I attempted to incorporate a group function into the line with @delta but couldn’t get it to behave as expected. So I ultimately when back to my original query which didn’t have this problem.

I would still love to hear any more suggestions about how to better handle a query like this.

Update 2:

Sorry for the lack of response on this question, I didn’t have a chance to investigate further until now.

Using Shlomi’s solution it looks like I had a problem because I was using a group by function when I read my @last variable but not when I set it. My code looked something like this:

CASE
    WHEN (@delta := count - @last) IS NULL THEN NULL
    WHEN (@last:= count ) IS NULL THEN NULL
    ELSE (CASE WHEN cumulative THEN @delta ELSE avg(count) END)
END AS delta

MySQL appears to process expressions that don’t contain aggregate functions in a first pass and ones that do in a second pass. The strange thing in the code above is that even when cumulative evaluates to true MySQL must see the AVG aggregate function in the ELSE clause and decides to evaluate the whole inner CASE expression in the second pass. Since @delta is set in an expression without an aggregate function it seems to be getting set on the first pass and by the time the second pass happens MySQL is done evaluating the lines that set @delta and @last.

Ultimately I seem to have found a fix by including aggregate functions in the first expressions as well. Something like this:

CASE
    WHEN (@delta := max(count) - @last) IS NULL THEN NULL
    WHEN (@last:= max(count) ) IS NULL THEN NULL
    ELSE (CASE WHEN cumulative THEN @delta ELSE avg(count) END)
END AS delta

My understanding of what MySQL is doing is purely based on testing and conjecture since I didn’t read the source code, but hopefully this will help others who might run into similar problems.

I am going to accept Shlomi’s answer because it really is a good solution. Just be careful how you use aggregate functions.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T02:22:11+00:00Added an answer on June 8, 2026 at 2:22 am

    I’ve researched this issue in depth, and wrote a few improvements on the above.

    I offer a solution in this post, which uses functions whose order can be expected. Also consider my talk last year.

    Constructs such as CASE and functions such as COALESCE have known underlying behavior (at least until this is changed, right?).

    For example, a CASE clause inspects the WHEN conditions one by one, by order of definition.

    Consider a rewrite of the original query:

    select 
      tick,
      CASE
        WHEN (@delta := count-@last) IS NULL THEN NULL
        WHEN (@last:=count ) IS NULL THEN NULL
        ELSE @delta
      END AS delta
    from 
      measurement,
      (select @last := 0) s_init
    ;
    

    The CASE clause has three WHEN conditions. It executes them by order until it meets the first that succeeds. I’ve written them such that the first two will always fail. It therefore executes the first, then turns to execute the second, then finally returns the third. Always.

    I thus overcome the problem of expecting order of evaluation, which is a real and true problem, mostly evident when you start adding more complex clauses such as GROUP BY, DISTINCT, ORDER BY and such.

    As a final note, my solution differs from yours in the first row on the result set — with yours’ it returns NULL, with mine it returns the delta between 0 and count. Had I used NULL I would have needed to change the WHEN conditions in some other way — making sure they would fail on NULL values.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

MYSQL I want to filter "orders" according to their items within a form's checkboxes.
According to the MySQL documentation regarding Optimizing Queries With Explain : * ALL: A
According to connects documentation the session should expire when the browser is closed: By
According to the PHP documentation, mysql_insert_id takes the last inserted id from the mysql
According to the documentation, joins, when used with the update statement, work in the
According to the documentation at mysqli_use_result One should not use mysqli_use_result() if a lot
I have data stored in a MySQL database according to the Entity-Attribute-Value pattern (EAV),
Using IQToolkit with MySQL, I would like to perform a LOCKING READ within a
According to mysql document Encoding with a 128-bit key length is used, but you
According to the MySQL Certification Guide, when --tab option is used, a SELECT ...

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.