简体   繁体   中英

sql CASE THEN statement

I have a table which I SUM one of the columns "amount". I then want to subtract a specific number from it and create another column with the CASE THEN. I can do it with php in the while loop successfully with if elseif but the client wants to be able to sort the results. I'm not super good with queries but trying to learn. Here is what I came up with by looking through all of the questions here. Will this work?

SELECT 
    accountNumber, 
    accountName, 
    sectorID, 
    territoryID, 
    regionID, 
    SUM(amount) AS totalSales 
    SELECT 
        CASE WHEN totalSales < 1001.00 THEN 1001.00 - totalSales
             WHEN totalSales < 2501.00 THEN 2501.00 - totalSales
             WHEN totalSales < 5001.00 THEN 5001.00 - totalSales
             WHEN totalSales < 10001.00 THEN 10001.00 - totalSales
             WHEN totalSales < 15001.00 THEN 15001.00 - totalSales
        END AS needed   
FROM 
    tblsales 
GROUP BY 
    accountName 
ORDER BY 
    accountName ASC    

You can't reference a column alias in the SELECT where it is defined. You have a really simply expression, so just repeat it:

SELECT accountNumber, accountName, sectorID, territoryID, regionID, 
       SUM(amount) AS totalSales,
       (CASE WHEN SUM(amount) < 1001.00 THEN 1001.00 - SUM(amount)
             WHEN SUM(amount) < 2501.00 THEN 2501.00 - SUM(amount)
             WHEN SUM(amount) < 5001.00 THEN 5001.00 - SUM(amount)
             WHEN SUM(amount) < 10001.00 THEN 10001.00 - SUM(amount)
             WHEN SUM(amount) < 15001.00 THEN 15001.00 - SUM(amount)
        END) AS needed  
FROM tblsales
GROUP BY accountName
ORDER BY accountName ASC

This is true in all dialects of SQL. The reason is simple: SQL does not specify the order of evaluation of expressions in a SELECT statement. Hence the expression using the alias might be evaluated before the alias is defined.

What about some flexibility? Imagine that you'll need to change/extend/etc. your margins... I would recommend to put them into a separate table:

create table margins(m_from int, m_to int);

insert into margins values
(0, 2501),(2501, 5001),(5001, 10001),(10001,15001),(15001,20001);

So now your code would look like as follows and you will not have to change it when your margins will be changed:

select v.*, m.m_to - totalSales as needed  from (
SELECT 
  accountNumber, accountName, sectorID, territoryID, regionID, SUM(amount) AS totalSales
FROM tblsales 
GROUP BY accountName) as v
join margins m
on (totalSales >= m_from and totalSales < m_to) 
ORDER BY accountName;

Here is your bit modified sqlfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM