Select with IF statement on postgresql - sql

I have a code like that:
select
tbl.person
,COUNT(distinct tbl.project)
,if (tbl.stage like '%SIGNED%') then sum(tbl.value) else '0' end if as test
from
my_table tbl
group by
1
And it returns me that error message:
SQL Error [42601]: ERROR: syntax error at or near "then"
I didn't got it. As I saw on documentation, the if statement syntax appears to be used correctly

IF is to be used in procedures, not in queries. Use a case expression instead:
select
tbl.person
,COUNT(distinct tbl.project)
,sum(case when tbl.stage like '%SIGNED%' then tbl.value else 0 end) as test
from
my_table tbl
group by
1
Notes:
tbl.stage is not part of the group by, so it should most probably be enclosed within the aggregate expression, not outside of it
all values returned by a case expression need to have the same datatype. Since sum(tbl.value) is numeric, the else part of the case should return 0 (number), not '0' (string).

In Postgres, I would recommend using filter:
select tbl.person, COUNT(distinct tbl.project)
sum(tbl.value) filter (where tbl.stage like '%SIGNED%') as test
from my_table tbl
group by 1;
if is control flow logic. When working with queries, you want to learn how to think more as sets. So the idea is to filter the rows and add up the values after filtering.

replace
if (tbl.stage like '%SIGNED%') then sum(tbl.value) else '0' end if as test
with
sum(case when tbl.stage like '%SIGNED%' then tbl.value end) as test

Related

Operator 'is true' for type 'long' not found for oracle sql query

I am trying to run this logic, where i get output as follows,
My code to get the below output field is shown below
select max(dtm) over (partition by name ,id )-current_date from mm
output
-4168
-4168
-4168
-4127
what i want is to run this logic along with 'case when' statement so i tried:
case when max(dtm) over (partition by name ,id )-current_date then 'yes'
else 'No' end as output
from mm
but i get an error as follows, not sure what went wrong in this logic.
Operator 'is true' for type 'long' not found
There are two forms of CASE expression. One is referred to as simple case expression and the other is referred to as searched case expression. The SQL in your question uses the latter, i.e. searched case expression. I believe you probably need simple case expression, i.e.
select case max(dtm) over (partition by name ,id ) - current_date
when -4168 then 'Yes'
else 'No'
end as answer
from mm
select
case when current_date-max(dtm) over (partition by name ,id ) < 30 then 'yes'
else 'No' end as 'output'
from mm

SQL CASE Expression

I need to write a sql statement(Oracle) where I can withdraw data from two diff tables and check for a condition and return a certain string.
My statement goes like this,
Select review.comments as comments,resort.resortid,resort.resortname
case review.comments
when resort.starrating>=4.5 and resort.starrating<5 then 'Excellent'
when resort.strarating>=4 and resort.starrating<4.5 then 'Great'
else 'Good'
end
from review, resort
order by resort.resortid;
When I run this I get a error: "FROM keyword not found where expected"and points to the c in line 2.
and if I change the from to line 2, it gives error: "SQL command not properly ended". and points to line 3 r in "case review.comments"
You need a JOIN, aggregation, and to fix the CASE expression syntax. I assume you want something like this:
Select res.resortid, res.resortname,
(case when avg(rev.starrating) >= 4.5 then 'Excellent'
when avg(rev.starrating) >= 4 then 'Great'
else 'Good'
end) as category
from review rev join
resort res
on rev.resortid = res.resortid
group by res.resortid, res.resortname
order by res.resortid;
You're mixing two variants of the case syntax. If you're going to supply conditions (not just values), you shouldn't have an expression following the case keyword:
case -- review.comments should be removed from here
when resort.starrating>=4.5 and resort.starrating<5 then 'Excellent'
when resort.strarating>=4 and resort.starrating<4.5 then 'Great'
else 'Good'
end
Syntax for case is
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;
so your code should look like this..
SELECT review.comments AS comments,
resort.resortid,
resort.resortname,
CASE
WHEN resort.starrating >= 4.5
AND resort.starrating < 5 THEN 'Excellent'
WHEN resort.strarating >= 4
AND resort.starrating < 4.5 THEN 'Great'
ELSE 'Good'
END
FROM review,
resort
ORDER BY resort.resortid;
Also just for your information, The comma between the two tables signifies a CROSS JOIN.
So your query is equivalent to:
select * from
FROM review
CROSS JOIN resort

how to use case with count function in oracle plsql

here is the query, i want to use case statement with count function in oracle.
Select case when count(*) > 0 then 'doSomething' else 'doSomething'
from student where student_name='faizan ahmed' and student_father='ahmed' and UPPER(student_dob)=UPPER('01-FEB-19');
please help me out, using plsql code.
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
For this purpose, use exists instead:
Select (case when exists (select 1
from student
where student_name = 'faizan ahmed' and
student_father = 'ahmed' and
upper(student_dob) = upper('01-FEB-19');
then 'doSomething'
else 'doSomethingElse'
end)
from dual;
EXISTS is usually more efficient than a count, because it can stop at the first matching row instead of aggregating the whole table.
You're missing an END for CASE:
SELECT CASE WHEN COUNT (*) > 0 THEN
'doSomething'
ELSE 'doSomething'
END --> This
FROM student
WHERE student_name = 'faizan ahmed'
AND student_father = 'ahmed'
AND UPPER (student_dob) = date '2019-02-01' -- No! UPPER ('01-FEB-19');
It is easier to spot if you format code you write.
Apart from that, STUDENT_DOB seems to be a date. If so, then don't compare it to a string (because '01-feb-19' IS a string) but to a date (date '2019-02-01' - it is a date literal, consists of the date keyword and yyyy-mm-dd value).
Also, it is strange that you used UPPER with that "date" string, but all your names are lowercase. Hm?

sql syntax is not working with group by clause

i am writing sql and I am stuck in the following line
select employeeid, (case paidL when'1'
Then
1
when '0'
Then
0
end) as 'paidLeave' from Lea order by employeeid group by 'paidLeave'
The above line if giving me error related to 'paidLeave'
Any help to improve the syntax to remove the error will be appreciated
Your case syntax is obviously wrong. But you have another error: Never use single quotes for column aliases. This is an example of an error waiting to happen.
It is best to use column and table names that do not need to be escaped. If they do, use square braces or double quotes.
The query you want should look like this:
select employeeid,
(case when paidL = '1' then 1
when paidl = '0 then 0
end) as paidLeave
from Lea
order by employeeid;
I have no idea what group by 'paidleave' is supposed to do. It is syntactically wrong on two fronts. If you want the sum, then the query would be something like:
select employeeid,
sum(case when paidL = '1' then 1
when paidl = '0 then 0
end) as paidLeave
from Lea
group by employeeid;
I think you need to study up on basic SQL syntax. There are many resources on the web and in books.
Your case syntax is all wrong, use this :
select employeeid, (case when paidL = '1'
Then 1
when paidL = '0'
Then 0
end) as paidLeave
from Lea
order by employeeid
Also, order by comes after group by!
Another thing, quote marks are used for strings, not column names. Maybe you meant ` but you don't have to do this because this is not a reserved word.
This whole query seems wrong, the group by doesn't make any sense if you have more then one employee, maybe you meant to group by emplooyeid and order by paidleave?
Maybe you meant to group by employee id and select the maximm paidLeave? in this case:
select employeeid, max((case when paidL = '1'
Then 1
when paidL = '0'
Then 0
end)) as paidLeave
from Lea
group by employeeid
order by employeeid
The CASE syntax is incorrect, it should follow the form;
CASE
WHEN <condition> THEN <result>
... (multiples of WHEN ... THEN ...)
ELSE <result>
END [Alias]
So something like;
CASE
WHEN [paidL] = '1' THEN 1
WHEN [paidL] = '0' THEN 0
END [paidLeave]
First of all, to better help you should provide the error. However, at first sight I would say your error is, you do not have included the employeeid column as part of the GROUP BY. Also I won't use a CASE statement for something you can resolve with casting. You could either CAST the paidL column to either INT or to BIT (just if values are only 0/1).
CAST([paidL] AS INT) paidL
CAST([paidL] AS BIT) paidL

group by expression must contain one column that is not an outer reference

Would somebody please take a look at this? I am trying to sum the total weight of all of our skus, but I need them to group either by foreign or domestic. SQL 2008 server.
Select
IMSYS01.on_hand_qty * IMSYS01.piece_weight,
IMSYS01.sku_no,
case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end as 'vLocation'
From
IMSYS01 IMSYS01
Where
(IMSYS01.sku_no < '99999' And
IMSYS01.velo_code <> 'X')
Group By
IMSYS01.on_hand_qty * IMSYS01.piece_weight, 'vLocation', IMSYS01.sku_no
Oh, the dreaded use of single quotes for an identifier. Don't use single quotes for an identifier. This is what you want:
Select IMSYS01.on_hand_qty * IMSYS01.piece_weight,
IMSYS01.sku_no,
(case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end) as vLocation
From IMSYS01 IMSYS01
Where (IMSYS01.sku_no < '99999' And IMSYS01.velo_code <> 'X')
Group By IMSYS01.on_hand_qty * IMSYS01.piece_weight,
(case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end),
IMSYS01.sku_no;
This is a great example of why you should never use single quotes for identifiers. It causes confusion. SQL Server supports other methods, but you don't even need to escape vlocation. It is a fine identifier just by itself.