Oracle SQL - Modify the Content Based on the Value From Another - sql

I keep getting the ORA-00905: missing keyword error here. Could you take a look please?
The task is to replace the content of the attribute with 'N/A' if another variable is equal to 'R', otherwise - keep the value as is.
Here is an extract of my code:
SELECT
CASE
WHEN SCHEMA.TABLE.VAR1 = 'R' THEN SCHEMA.TABLE.VAR2 = 'N/A'
ELSE SCHEMA.TABLE.VAR2
END AS NEW_NAME

If you want a select, the column alias goes after the select. = is not allowed in the then clause:
SELECT (CASE WHEN SCHEMA.TABLE.VAR1 = 'R' THEN 'N/A'
ELSE SCHEMA.TABLE.VAR2
END) AS NEW_NAME
Note: You should use table aliases, so the query is easier to write and to read:
SELECT (CASE WHEN t.VAR1 = 'R' THEN 'N/A'
ELSE t.VAR2
END) AS NEW_NAME,
. . .
FROM SCHEMA.TABLE t . ..

You should be using an update here rather than a select, if you intend to change the data in your SQL table:
UPDATE yourTable
SET SCHEMA.TABLE.VAR2 = 'N/A'
WHERE SCHEMA.TABLE.VAR1 = 'R'
If you need to do a select here, then use the following:
SELECT
CASE WHEN SCHEMA.TABLE.VAR1 = 'R' THEN 'N/A' ELSE SCHEMA.TABLE.VAR2 END AS NEW_NAME
FROM yourTable

Related

Case Expression on a created column using Microsoft SQL

Within a view I put put together a select statement within a case and delcared it as a column. The column name is 'IR2'
How can I case off of the column 'IR2'?
I end up getting an error which says 'Invalid Column Name 'IR2'.
What are my work around options?
case when r.ana = 'nh3' and r.serv='energy' and exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end as IR2,
CASE IR2 WHEN 'Released' then
''
ELSE
'*'
END AS IR
You can use a subquery or CTE. But another fun way in SQL Server is using outer apply:
select v.IR2,
(case IR2 when 'Released' then '' else '*' end) as ir
from . . . outer apply
(values (case when r.ana = 'nh3' and r.serv='energy' and
exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa
end)
) v(IR2)
CTE would be the best choice. If you want to continue with current statement, you need to put a copy of the case statement in other case statement. Very messy code.
SELECT
case when r.ana = 'nh3' and r.serv='energy' and
exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end as IR2,
CASE
(case when r.ana = 'nh3' and r.serv='energy'
and exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end)
WHEN 'Released' then
''
ELSE
'*'
END AS IR

Query timeout increased but script fails to execute

When i execute this script on my remote database it gives me query timeout error. I've increased the timeout on my database but still have this error. I've been told if i'm able to optimized the script to make it simple it might work.
SELECT TOP 8 MIN( CASE WHEN pic_alb_love.pic=users_pics.pic
AND pic_alb_love.email = 'try#mail.com' THEN 'User' ELSE 'Guest' END)AS answer_one,
MIN ( CASE WHEN favorites.pic=users_pics.pic AND favorites.email = 'try#mail.com' THEN 'good' ELSE 'Bad'
END)AS answer2,
(CASE WHEN RTRIM (users_pics.upload_type) = 'wow' THEN 'loaded' ELSE
CASE WHEN RTRIM (users_pics.upload_type)= 'hey' THEN 'added' ELSE
CASE WHEN RTRIM (users_pics.upload_type) = 'check' THEN 'Changed' END END END)as up_ans,
(CASE WHEN RTRIM (users_pics.upload_type) = 'sample1' THEN 'new' ELSE
CASE WHEN RTRIM (users_pics.upload_type) = 'sample2' THEN 'existing' ELSE
CASE WHEN RTRIM (users_pics.upload_type) = 'sample3' THEN 'Profile Picture' END END END) as exs,
COUNT(DISTINCT users_pics.pic) as total,RTRIM (users_pics.wardrobe) as wardrobe,
fname,users_pics.wardrobe,
MIN (make)as make,MIN (htags)as htags, RTRIM (profile.profile_id) as profile_id,
users_pics.email,profile.profile_pix, RTRIM (profile.gender) as gender,
users_pics.time_group,profile.fpage,up_user_id, MIN (u_pic_id) as u_pic_id, MIN (users_pics.pic) as pic
FROM users_pics
LEFT join profile on users_pics.email = profile.email
LEFT join favorites on users_pics.pic = favorites.pic
LEFT JOIN pic_alb_love on users_pics.pic = pic_alb_love.pic
left join friends on users_pics.email = friends.resp_email
WHERE req_email = 'try#mail.com' and pic_enable='enable' or pic_view='Public'
GROUP BY users_pics.upload_type,profile.fname,profile.profile_id,users_pics.wardrobe,
users_pics.email, profile.gender,users_pics.time_group,profile.profile_pix, profile.fpage,up_user_id
ORDER BY MIN (users_pics.u_pic_id) DESC
Increasing timeout can help, but you should also check if your query isn't blocked by others operations like INSERT/UPDATE or open transaction.
The easiest way is to install and use sp_whoisactive procedure.
Second you don't need to nest CASE like you did:
(CASE WHEN RTRIM (users_pics.upload_type) = 'wow' THEN 'loaded' ELSE
CASE WHEN RTRIM (users_pics.upload_type)= 'hey' THEN 'added' ELSE
CASE WHEN RTRIM (users_pics.upload_type) = 'check' THEN 'Changed' END END END)as up_ans,
to
CASE RTRIM (user_pics.upload_type)
WHEN 'wow' THEN 'loaded'
WHEN 'hey' THEN 'added'
WHEN 'check' THEN 'changed'
ELSE NULL /* or your value like 'unknown' */
END AS up_ans
Next thing: you RTRIM almost on every string value, you should sanitize your input during inserting, unless you need spaces/tabs/newline and so on.
This way your query won't need RTRIM and can utilize index if exists any.
/* New values */
INSERT INTO table_name(...) VALUES (LTRIM(RTRIM(value...)))
/* Existing ones */
UPDATE table_name
SET col = LTRIM(RTRIM(col))
SQL Parser will understand wall of text, human will need time to do it.
I know we can argue about code style but remember you write code for people. Good readable code allow you to spot errors earlier and it is a hell easier to maintain in the future for you and your successors:
1) One selected value one line
2) The same order in SELECT and GROUP BY
3) Aggregated columns at end
4) You can use aliases no need for fully qualified names
5) No ambiguous column names, always specify from which table
6) SQL syntax UPPER CASE
7) Allign your code
Your query in more human readable from:
SELECT TOP 8
[up_user_id] /* Always add from which table even if it is unique column name, because in future you may get ambigous column */
,[fname]
,[profile_id] = RTRIM(profile.profile_id)
,[up_ans] = CASE RTRIM(users_pics.upload_type)
WHEN 'wow' THEN 'loaded'
WHEN 'hey' THEN 'added'
WHEN 'check' THEN 'changed'
ELSE NULL
END
,[exs] = CASE RTRIM(users_pics.upload_type)
WHEN 'sample1' THEN 'new'
WHEN 'sample2' THEN 'existing'
WHEN 'sample3' THEN 'Profile Picture'
ELSE NULL
END
,[wardrobe] = RTRIM(users_pics.wardrobe)
,users_pics.email
,[gender] = RTRIM(profile.gender)
,users_pics.time_group
,profile.profile_pix
,profile.fpage
,[answer_one] = MIN(CASE
WHEN pic_alb_love.pic=users_pics.pic THEN 'User'
ELSE 'Guest'
END)
,[answer2] = MIN(CASE
WHEN favorites.pic = users_pics.pic AND favorites.email = 'try#mail.com' WHEN 'good'
ELSE 'Bad'
END)
,[total] = COUNT(DISTINCT users_pics.pic)
,[make] = MIN(make)
,[htags] = MIN(htags)
,[u_pic_id] = MIN(u_pic_id)
,[pic] = MIN(users_pics.pic)
FROM users_pics /* you can use alias like AS up */
LEFT JOIN profile
ON users_pics.email = profile.email
LEFT JOIN favorites
ON users_pics.pic = favorites.pic
LEFT JOIN pic_alb_love
ON users_pics.pic = pic_alb_love.pic
LEFT JOIN friends
ON users_pics.email = friends.resp_email
WHERE
req_email = 'try#mail.com'
AND pic_enable = 'enable'
OR pic_view = 'Public'
GROUP BY
up_user_id
,profile.fname
,profile.profile_id
,users_pics.upload_type
,users_pics.wardrobe
,users_pics.email
,profile.gender
,users_pics.time_group
,profile.profile_pix
,profile.fpage
ORDER BY MIN(users_pics.u_pic_id) DESC
After you check that your query is not blocked during selecting data you can think about:
checking indexes on your tables
add WHERE condition to fetch smaller set, maybe you can use some update_date > current_date - 2 weeks
think to optimize query because now it does grouping and ordering which needs time to complete.
your WHERE condition, are you sure it shouldn't be:
.
WHERE (req_email = 'try#mail.com'
AND pic_enable = 'enable')
OR pic_view = 'Public'

Case sentence using SQL

I am using double case sentence to get a value from column in a table based on 2 conditions that are available in 2 other columns in same table , and else (otherwise) the function should give null when it is null or 0 when it is 0 .
Example of code is below :
CASE CODE
WHEN 'ABC'
CASE NAME WHEN 'XYZ'
THEN 'VALUE'
ELSE NULL
END
ELSE NULL
END
The problem is if I use NULL after else then it gives all ( both null values and values with 0 ) as NULL , or if I use 0 instead of NULL after ELSE then both null and 0 values are given as 0 .
I have tried to write the sentence in many ways but I dont know its not working . Hopefully somebody can give me some good solution regarding this.
CASE WHEN CODE = 'ABC' AND NAME = 'XYZ' THEN 'VALUE' ELSE NULL END
I believe you want:
CASE WHEN CODE = 'ABC' AND NAME = 'XYZ' THEN 'VALUE' ELSE NULL END
This structure of the CASE statement is more flexible than sticking the field name before WHEN.
Are you trying to do something like this?
(CASE when CODE = 'ABC' and NAME = 'XYZ'
THEN 'VALUE'
when code = '0' or name = '0'
then '0'
ELSE NULL
end)
Or perhaps it is this (based on the fact that you are trying to get something from a column):
(CASE when CODE = 'ABC' and NAME = 'XYZ'
THEN value
when value is NULL or value = 0
then value
ELSE NULL
end)
Based on your comment, I think this will work:
(CASE when CODE = 'ABC' and NAME = 'XYZ'
THEN value
ELSE NULL
end)
Or is it this:
(CASE when CODE = 'ABC' and NAME = 'XYZ' and value <> '0'
THEN 'value'
when CODE = 'ABC' and NAME = 'XYZ' and value = '0'
then '0'
ELSE NULL
end)
However, I think this is equivalent to your original nested two-case version.

SQL case with different fields to check from same table

I have the following problem:
I have a select statement that includes a case part. Up til there it is easy the problem is that the case includes a check against another field in the same table.
select h.id,
case h.value
when 'P' then 'test'
when '' then 'failed'
when 'D' then 'passed'
else null end
as info,
b.text,
case h.diag
when h.value = '' [or 'failed' not sure tried both and didn't work]
else h.diag end
as diag1, h.date from valuetab h, texttab b where h.id=b.id
I want to have h.diag only to show values when h.value is not failed.
I always get the mistake that the = should be concat.. but that doesn't make sense in my eyes.
Any ideas??
Thats for all your help.
You can also write a case statement with your expression in a different place i.e.
SELECT CASE WHEN X = 1 THEN 'Y' WHEN X = 2 THEN 'Z'
I think what you want to do is something more like this:
SELECT CASE WHEN h.value = '' THEN h.diag end
Use the other form of case statement, which doesn't specify a column you want to look at:
select case
when column1 = 2 then 'Foo'
when other_column = 'blah' then 'Bar'
end
from table
The problem with using case column1 when... is that it implicitly compares column1 to each when clause. You can't then include a comparison to some other column in it.
You are missing a THEN portion of the WHEN clause, and specifying a condition where you could specify a value:
case h.value
when '' THEN NULL
else h.diag end
Ok got it....
after the 2nd case the "h.diag" must be removed....
so it is
case
when h.value = '' then null
else h.diag end
as diag1,

SQL: Alias Column Name for Use in CASE Statement

Is it possible to alias a column name and then use that in a CASE statement? For example,
SELECT col1 as a, CASE WHEN a = 'test' THEN 'yes' END as value FROM table;
I am trying to alias the column because actually my CASE statement would be generated programmatically, and I want the column that the case statement uses to be specified in the SQL instead of having to pass another parameter to the program.
This:
SELECT col1 as a,
CASE WHEN a = 'test' THEN 'yes' END as value
FROM table;
...will not work. This will:
SELECT CASE WHEN a = 'test' THEN 'yes' END as value
FROM (SELECT col1 AS a
FROM TABLE)
Why you wouldn't use:
SELECT t.col1 as a,
CASE WHEN t.col1 = 'test' THEN 'yes' END as value
FROM TABLE t;
...I don't know.
I think that MySql and MsSql won't allow this because they will try to find all columns in the CASE clause as columns of the tables in the WHERE clause.
I don't know what DBMS you are talking about, but I guess you could do something like this in any DBMS:
SELECT *, CASE WHEN a = 'test' THEN 'yes' END as value FROM (
SELECT col1 as a FROM table
) q
#OMG Ponies - One of my reasons of not using the following code
SELECT t.col1 as a,
CASE WHEN t.col1 = 'test' THEN 'yes' END as value
FROM TABLE t;
can be that the t.col1 is not an actual column in the table. For example, it can be a value from a XML column like
Select XMLColumnName.value('(XMLPathOfTag)[1]', 'varchar(max)')
as XMLTagAlias from Table
It should work. Try this
Select * from
(select col1, col2, case when 1=1 then 'ok' end as alias_col
from table)
as tmp_table
order by
case when #sortBy = 1 then tmp_table.alias_col end asc
I use CTEs to help compose complicated SQL queries but not all RDBMS' support them. You can think of them as query scope views. Here is an example in t-sql on SQL server.
With localView1 as (
select c1,
c2,
c3,
c4,
((c2-c4)*(3))+c1 as "complex"
from realTable1)
, localView2 as (
select case complex WHEN 0 THEN 'Empty' ELSE 'Not Empty' end as formula1,
complex * complex as formula2
from localView1)
select *
from localView2
Nor in MsSql
SELECT col1 AS o, e = CASE WHEN o < GETDATE() THEN o ELSE GETDATE() END
FROM Table1
Returns:
Msg 207, Level 16, State 3, Line 1
Invalid column name 'o'.
Msg 207, Level 16, State 3, Line 1
Invalid column name 'o'.
However if I change to CASE WHEN col1... THEN col1 it works
If you write only equal condition just:
Select Case columns1 When 0 then 'Value1'
when 1 then 'Value2' else 'Unknown' End
If you want to write greater , Less then or equal you must do like this:
Select Case When [ColumnsName] >0 then 'value1' When [ColumnsName]=0 Or [ColumnsName]<0 then
'value2'
Else
'Unkownvalue' End
From tablename
Thanks
Mr.Buntha Khin
SELECT
a AS [blabla a],
b [blabla b],
CASE c
WHEN 1 THEN 'aaa'
WHEN 2 THEN 'bbb'
ELSE 'unknown'
END AS [my alias],
d AS [blabla d]
FROM mytable
Not in MySQL. I tried it and I get the following error:
ERROR 1054 (42S22): Unknown column 'a' in 'field list'
In MySql, alice name may not work, therefore put the original column name in the CASE statement
SELECT col1 as a, CASE WHEN col1 = 'test' THEN 'yes' END as value FROM table;
Sometimes above query also may return error, I don`t know why (I faced this problem in my two different development machine). Therefore put the CASE statement into the "(...)" as below:
SELECT col1 as a, (CASE WHEN col1 = 'test' THEN 'yes' END) as value FROM table;
Yes, you just need to add a parenthesis :
SELECT col1 as a, (CASE WHEN a = 'test' THEN 'yes' END) as value FROM table;
make it so easy.
select columnnameshow = (CASE tipoventa
when 'CONTADO' then 'contadito'
when 'CREDITO' then 'cred'
else 'no result'
end) from Promocion.Promocion