PostgreSQL - Aliases column and HAVING
Asked Answered
D

3

22
SELECT  
CASE WHEN SUM(X.Count)*3600 is null THEN  '0'  
            ELSE  
            SUM(X.Count)*3600  
       END AS PJZ,  
       X.Mass  
FROM X  
WHERE X.Mass > 2000  
HAVING ((X.Mass / PJZ * 100) - 100) >= 10;

Getting: ERROR: Column »pjz« doesn't exists.

How can I do something like this?

Diphyllous answered 22/9, 2011 at 7:23 Comment(1)
Why can't I use alias in a count(*)Walker
E
7

Wrap it into a derived table:

SELECT CASE 
          WHEN PJZ = 0 THEN 100
          ELSE PJZ
       END as PJZ,
       mass
FROM (
    SELECT CASE 
             WHEN SUM(X.Count)*3600 is null THEN '0'  
             ELSE SUM(X.Count)*3600  
           END AS PJZ,  
           X.Mass  
    FROM X  
    WHERE X.Mass > 2000  
    GROUP BY X.mass
) t
WHERE PJZ = 0 
   OR ((X.Mass / PJZ * 100) - 100) >= 10;

(Note that I added the missing group by as otherwise the query would not be valid)

Enchondroma answered 22/9, 2011 at 7:41 Comment(3)
But now I've got the problem with division by zero. PJZ could be zero.Diphyllous
Then exclude the rows WHERE PJZ is zero. Or depending on your requirements return 1 (or any other non-zero value) in the CASE statementEnchondroma
I can't exclude the rows, because I want to see them, too. If PJZ is 0 this: ((X.Mass / PJZ * 100) - 100) should show 100 for me. So I need another IF ELSE...Diphyllous
A
13

You can't use aliases in a having, and have to duplicate the statement in the having cluause. Since you only want to check for null, you could do this:

SELECT coalesce(SUM(X.Count)*3600, 0) AS PJZ, X.Mass
FROM X
WHERE X.Mass > 2000
HAVING ((X.Mass / coalesce(SUM(X.Count)*3600, 0) * 100) - 100) >= 10; 
Acquaint answered 22/9, 2011 at 7:34 Comment(0)
I
10

Other option is to surround query by WITH statement - for example:

WITH x as (
  SELECT coalesce(SUM(X.Count)*3600, 0) AS PJZ, X.Mass
  FROM X
  WHERE X.Mass > 2000
)
SELECT * from X WHERE PJZ >=10

It is far better then code duplication in my opinion

Indented answered 14/5, 2021 at 15:34 Comment(1)
This is beautiful. 💫Rue
E
7

Wrap it into a derived table:

SELECT CASE 
          WHEN PJZ = 0 THEN 100
          ELSE PJZ
       END as PJZ,
       mass
FROM (
    SELECT CASE 
             WHEN SUM(X.Count)*3600 is null THEN '0'  
             ELSE SUM(X.Count)*3600  
           END AS PJZ,  
           X.Mass  
    FROM X  
    WHERE X.Mass > 2000  
    GROUP BY X.mass
) t
WHERE PJZ = 0 
   OR ((X.Mass / PJZ * 100) - 100) >= 10;

(Note that I added the missing group by as otherwise the query would not be valid)

Enchondroma answered 22/9, 2011 at 7:41 Comment(3)
But now I've got the problem with division by zero. PJZ could be zero.Diphyllous
Then exclude the rows WHERE PJZ is zero. Or depending on your requirements return 1 (or any other non-zero value) in the CASE statementEnchondroma
I can't exclude the rows, because I want to see them, too. If PJZ is 0 this: ((X.Mass / PJZ * 100) - 100) should show 100 for me. So I need another IF ELSE...Diphyllous

© 2022 - 2025 — McMap. All rights reserved.