2

I am no SQL expert but I can't see why I'm getting an error with the following code: http://sqlfiddle.com/#!3/2de76/7. Please can someone tell me what is wrong with this. Thanks.

DECLARE @total INT
SET @total = 0
SELECT
    s1.RowCountID,
    CASE
        WHEN s1.dayTotal < s2.dayTotal      THEN @total = @total
        WHEN s1.dayTotal > s2.dayTotal      THEN @total = @total + (s1.dayTotal - s2.dayTotal)
    END     AS res,
    s1.dayTotal,
    s2.dayTotal
FROM simple_summary s1
JOIN simple_summary s2 ON s2.RowCountID = s1.RowCountID - 1
ORDER BY s1.RowCountID ASC

The expected output:

rowCount,res,dayTotal,dayTotal
1,3,3,0
2,4,4,3
3,4,3,4
4,7,6,3
3
  • Are you attempting to get a running total in the @Total variable? Commented Sep 18, 2015 at 8:30
  • sqlfiddle.com/#!3/2de76/19/0 Check Commented Sep 18, 2015 at 8:31
  • Sorry @user5151179 yes I am aiming to do that :) Commented Sep 18, 2015 at 8:43

3 Answers 3

3

You're trying to use the CASE's THEN to alter the value of a variable. Doesn't work like that. This, however, works, and looks more close to what you might want to achieve:

DECLARE @total INT
SET @total = 0
SELECT 
    s1.RowCountID,
    CASE
        WHEN s1.dayTotal < s2.dayTotal      THEN @total
        WHEN s1.dayTotal > s2.dayTotal      THEN (s1.dayTotal - s2.dayTotal)
    END     AS res,
    s1.dayTotal,
    s2.dayTotal
FROM simple_summary s1
JOIN simple_summary s2 ON s2.RowCountID = s1.RowCountID - 1
ORDER BY s1.RowCountID ASC

PS - your CASE doesn't take the possibility of s1.dayTotal = s2.dayTotal into account. Not sure that's okay.

PPS - if you want the second WHEN to sum up the total AND the difference, use

WHEN s1.dayTotal > s2.dayTotal      THEN @total+(s1.dayTotal - s2.dayTotal)

PPPS - This seems to produce the desired resultset:

select a.RowCountID, case when b.diff > 0 then a.res+b.diff else a.res end as res, a.daytotal1, a.daytotal2  from
(
SELECT 
    s1.RowCountID,
    CASE
        WHEN s1.dayTotal < s2.dayTotal      THEN s2.dayTotal
        WHEN s1.dayTotal >= s2.dayTotal     THEN s1.dayTotal
    END     AS res,
    s1.dayTotal as dayTotal1,
    s2.dayTotal as dayTotal2,
    s2.dayTotal - s1.dayTotal as diff
FROM simple_summary s1
JOIN simple_summary s2 ON s2.RowCountID = s1.RowCountID - 1
  ) a 
  left join
(
  SELECT 
    s1.RowCountID,
    CASE
        WHEN s1.dayTotal < s2.dayTotal      THEN s2.dayTotal
        WHEN s1.dayTotal >= s2.dayTotal     THEN s1.dayTotal
    END     AS res,
    s1.dayTotal as dayTotal1,
    s2.dayTotal as dayTotal2,
    s2.dayTotal - s1.dayTotal as diff
FROM simple_summary s1
JOIN simple_summary s2 ON s2.RowCountID = s1.RowCountID - 1
) b on a.rowcountID = b.rowcountID+1
order by a.rowcountID

Not sure what this kind of self-joining query is named, but it should have a name :)

Hope it works well!

Sign up to request clarification or add additional context in comments.

8 Comments

I think this misses the point of the OP's use of a variable, which is to sum together the totals of different rows.
Sorry for a delay. What I would ultimately like is for res to be 3,4,4,7 - it must be a cumulative figure.
Yeah, that's what I meant with "sum together the totals of different rows" too. This answer still doesn't do that even with the edit. @Ukuser32 I think it would be clearer to other users if you could include the sample data and the expected output from your comment directly in your question.
Done - I was just wanting the query to run not expecting us to fix it as well :)
Could you explain the res column? what do you want it to contain, exactly?
|
1

You need to remove "@total =" from the case statement.

DECLARE @total int
SET @total = 0

SELECT
  s1.RowCountID,
  CASE
    WHEN s1.dayTotal < s2.dayTotal THEN @total
    WHEN s1.dayTotal > s2.dayTotal THEN @total + (s1.dayTotal - s2.dayTotal)
  END AS res,
  s1.dayTotal,
  s2.dayTotal
FROM simple_summary s1
JOIN simple_summary s2
  ON s2.RowCountID = (s1.RowCountID - 1)
ORDER BY s1.RowCountID ASC

Comments

0

Ok after further investigation (and finding how to get cumulative sum), the following is the correct code to make it work (but with the addition of the case command):

SELECT
    s1.RowCountID,
      SUM(
      CASE
        WHEN s1.dayTotal < s2.dayTotal      THEN 0
        WHEN s1.dayTotal > s2.dayTotal      THEN s1.dayTotal - s2.dayTotal
      END) OVER(
           ORDER BY s1.RowCountID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
      ) AS res2,
    s1.dayTotal,
    s2.dayTotal
FROM simple_summary s1
JOIN simple_summary s2 ON s2.RowCountID = s1.RowCountID - 1
ORDER BY s1.RowCountID ASC

My actual issue is I also use MySQL (I was experimenting to see if it was possible elsewhere) so the next question is how this would look in MySQL?? That will take some further investigations!!

2 Comments

I considered answering with this already, except you put "SQL Server 2008" in your question title and this is only supported starting with SQL Server 2012. (Note: it does work on SQLFiddle's "MS SQL Server 2008" mode, but that isn't actually a 2008 version.)
Ah! Maybe I should change the title. It was only because I was using SQL fiddle!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.