SQL CASE Expression - sql

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

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

Select with IF statement on postgresql

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

CASE expression - add one more condition to the WHEN part

I have created a PL/SQL function where I have a case expression in a SQL query. This is working fine, but when I add another when condition it will not compile. Even if I use when ... and 2 > 1, this is also not compiling.
In the below code, the commented part is not working properly.
What I want is to add one more check in my when clause. Please advise.
create or replace function FUNCTION_NAME (date1 in varchar2,value1 in varchar2)
RETURN date
IS
date2 date;
BEGIN
SELECT D DATE2
INTO DATE2 FROM (SELECT CASE (SELECT TO_DATE(MAX(G.DATE3),'DD-MON-YYYY')
FROM TABLE1 G,
TABLE2 N
WHERE G.DATE3=N.DATE3)
WHEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
/* AND MONTHS_BETWEEN (LAST_DAY(TO_DATE(SYSDATE)),
LAST_DAY(TO_DATE(TO_CHAR(DATE1),'DD-MON-YYYY'))) */
THEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
ELSE
TO_DATE('31-DEC-99','DD-MON-YYYY')
END D
FROM DUAL);
RETURN DATE2;
END;
What you have is a case expression (not a case statement).
Case expressions are of two kinds: "simple" (case <expr> when val1 then ... when val2 then... etc.) and "searched" ( case when condition1 then ... when condition2 then ... etc.)
You wrote your case expression as a simple case expression. You can't, then, add conditions to the WHEN part. You must change the case expression to be "searched" all the way through.
case when (select ...) = last_day(...) AND <your commented condition> THEN .....
EDIT - copying part of a clarifying comment below my Answer.
Simple case expression:
case x when 1 then ....
Can also be written as searched case expression:
case when x = 1 then ....
These two are logically equivalent. However, if we want to add "AND 3 > 1" to the WHEN part, that works only in the searched form of the case expression.
There are two flavours of CASE.
Simple CASE:
select case dummy
when 'X' then 1
end as case_demo
from dual;
Searched CASE:
select case
when dummy = 'X' then 1
end as case_demo
from dual;
In your query you are mixing them like this, which won't work:
select case dummy
when 'X' and 1 = 1
then 1
end as case_demo
from dual;
If you switch to a "searched CASE", then you can add more when conditions:
select case
when dummy = 'X' and 1 = 1
then 1
end as case_demo
from dual;

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.