Case when in Oracle - ora-00923

select FIRST_NAME,LAST_NAME,SALARY
Case
When SALARY > 15000 then 'high'
When SALARY < 10000 then 'low'
ELSE 'super low'
END As salary_group
from hr.employees
On running the query, I get the follwoing:
ORA-00923: FROM keyword not found where expected
table

There's a syntax error in your query, you need a comma after SALARY column:
select FIRST_NAME,LAST_NAME,SALARY,
Case
When SALARY > 15000 then 'high'
When SALARY < 10000 then 'low'
ELSE 'super low'
END As salary_group
from hr.employees

Related

Need to check multiple condition for Oracle query

I have a query below. i can check two conditions. If 'AAA' occurs it will show "AAA" with its id else it will show 'BBB'. I need to check more conditions like
if 'AAA' occurs print "AAA" with its id
else 'BBB' occurs print "BBB" with its id
else 'ccc' occurs print "CCC" with its id
how to do this?
SELECT DISTINCT institution_id,
CASE
WHEN count(*) over(PARTITION BY institution_id) >=5 THEN 'AAA'
WHEN count(*) over(PARTITION BY institution_id) >=5 THEN 'BBB'
END AS status
FROM table
WHERE data LIKE '% AAA%'
WITH
INSTITUTION_COUNT
AS
( SELECT INSTITUTION_ID, COUNT (*) AS INSTITUTION_COUNT
FROM INSTITUTION
GROUP BY INSTITUTION_ID)
SELECT E.INSTITUTION_ID AS INSTITUTION_ID,
DC.INSTITUTION_COUNT AS INSTITUTION_COUNT,
CASE
WHEN DC.INSTITUTION_COUNT < 5 THEN 'Low'
WHEN DC.INSTITUTION_COUNT >= 5 THEN 'High'
END AS STATUS
FROM INSTITUTION E, INSTITUTION_COUNT DC
WHERE E.INSTITUTION_ID = DC.INSTITUTION_ID;

SQLSyntaxErrorException: ORA-00933: SQL command not properly ended in oracle

can anyone help me with this query?
select trans_dt,trans_acc_no,trans_desc,trans_amt,transaction_type as trans_type , replace(trans_type,'credit','CR'), replace(trans_type,'debit','DB') from bank_transaction
where (trans_amt>10000 and cust_type != bank_rd_account)
order by(trans_type asc and trans_date desc) ;
remove and between order by clause - it is giving u the syntax error
select
trans_dt,
trans_acc_no,
trans_desc,
trans_amt,
transaction_type as trans_type,
replace(trans_type, 'credit', 'CR'),
replace(trans_type, 'debit', 'DB')
from
bank_transaction
where
(
trans_amt > 10000
and cust_type != bank_rd_account
)
order by
trans_type asc,
trans_date desc
Please refer the url for more reference about order by
https://www.techonthenet.com/oracle/order_by.php
In sql order cannot be given inside brackets.it should be given as below
Example:
SELECT * FROM table_name ORDER BY column1 ASC|DESC, column2 ASC|DESC
Query you required is given below:
select
trans_dt,
trans_acc_no,
trans_desc,
trans_amt,
transaction_type as trans_type,
replace(trans_type, 'credit', 'CR'),
replace(trans_type, 'debit', 'DB')
from
bank_transaction
where
trans_amt > 10000
and cust_type != bank_rd_account
order by
trans_type asc,
trans_date desc

How to retrieve only columns which have at least one not null value in any row in Oracle

I have table structure and data as below
https://ibb.co/mkGp67
I want a SQL Query to retrieve data only for those columns which have at least one not null value in it, in above case i want data comes out to be
https://ibb.co/mz9967
i.e. i don't need column Col2, Col5 and Col6, also which column having all null value is not fixed.
Please let me know the SQL query which retreive data that having only those column which having not null value with data as above.
As far, as I know, you will not be able to achieve this with an SQL query. One of the strong assumptions of SELECT statements is that the list of returned columns is static - defined in the query, not by the data. Even for PIVOT queries (available - as far, as I know - since Oracle 11), the list of columns is defined in the query, by providing a list of values to be converted to columns has to be explicitly given.
What you are looking for is some kind of code, dynamically generating the query. This can be PL/SQL, returning cursor references or any application code.
Edit:
What you could do with a query, is to have a clear information on which columns do contain nulls, which do not, etc. It could look something like this:
SELECT CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col1) = 0 THEN 'all NULLs'
WHEN COUNT(Col1) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col1NullStatus,
CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col2) = 0 THEN 'all NULLs'
WHEN COUNT(Col2) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col2NullStatus,
CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col3) = 0 THEN 'all NULLs'
WHEN COUNT(Col3) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col3NullStatus,
CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col4) = 0 THEN 'all NULLs'
WHEN COUNT(Col4) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col4NullStatus,
CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col5) = 0 THEN 'all NULLs'
WHEN COUNT(Col5) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col5NullStatus,
CASE
WHEN COUNT(*) = 0 THEN 'no rows'
WHEN COUNT(Col6) = 0 THEN 'all NULLs'
WHEN COUNT(Col6) = COUNT(*) THEN 'no NULLs'
ELSE 'some NULLs'
END Col6NullStatus
FROM myTable
See SQL Fiddle for the above.
Edit 2:
And the output of this query would look something like this:
Col1NullStatus | Col2NullStatus | Col3NullStatus | Col4NullStatus | Col5NullStatus | Col6NullStatus
---------------+----------------+----------------+----------------+----------------+----------------
no NULLs | all NULLs | some NULLs | no NULLs | all NULLs | all NULLs
This is the format, you could be using, to post your input data and expected results.
So, since you give no no formal table structure, and you seem to be confusing numbers and chars(s), I will do my best to try and make a query that will at least produce the results you want.
create table foo as (
col1 varchar(10),
col2 varchar(10),
col3 varchar(10),
col4 varchar(10),
col5 varchar(10),
col6 varchar(10)
);
select *
CASE cust1 WHEN null then 'null' else cust1 as cust1 end,
CASE cust2 WHEN null then 'null' else cust1 as cust1 end,
CASE cust3 WHEN null then 'null' else cust1 as cust1 end,
CASE cust4 WHEN null then 'null' else cust1 as cust1 end,
CASE cust5 WHEN null then 'null' else cust1 as cust1 end,
CASE cust6 WHEN null then 'null' else cust1 as cust1 end
from foo ;
As per below query , I able to get not null columns at row-level col1,col3 and col4.
Query :
select 'col1' as "Name",col1 from temp
where exists (select 1
from temp
group by to_char(col1)
having (count(to_char(col1)))> 0)
union all
select 'col2' as "Name",to_char(col2) from temp
where exists (select 1
from temp
group by to_char(col2)
having (count(to_char(col2)))> 0)
union all
select 'col3' as "Name" , to_char(col3) from temp
where exists (select 1
from temp
group by to_char(col3)
having (count(to_char(col3)))> 0)
union all
select 'col4'as "Name" , to_char(col4) from temp
where exists (select 1
from temp
group by to_char(col4)
having (count(to_char(col4)))> 0)
union all
select 'col5' as "Name" , to_char(col5) from temp
where exists (select 1
from temp
group by to_char(col5)
having (count(to_char(col5)))> 0)
union all
select 'col6' as "Name" , to_char(col6) from temp
where exists (select 1
from temp
group by to_char(col6)
having (count(to_char(col6)))> 0)
output:
col1 A
col1 B
col1 C
col1 D
col3 10
col3 20
col3 -
col3 10
col4 12
col4 23
col4 34
col4 43
I tried to make this output of rows to columns but I couldn't make it in single query ... Hope this will be helpful ...
I would do this usually in three steps.
Firstly, make sure that the table statistics are up to date. Check if last_analyzed is later than the last change to the table.
SELECT last_analyzed FROM user_tables WHERE table_name = 'MYTABLE';
If in doubt, update the statistics with
BEGIN dbms_stats.gather_table_stats('MYSCHEMA','MYTABLE'); END;
/
Now, the view user_tab_columns has a column num_nulls. This is the number of rows where this column is NULL. If the value is the same than the number of rows in the table, all rows are NULL. This can be used to let Oracle generate the required SQL:
WITH
qtab AS (SELECT owner, table_name, num_rows
FROM all_tables
WHERE owner='SCOTT' -- change to your schema
AND table_name='EMPLOYEES' -- change to your table name
),
qcol AS (SELECT owner, table_name, column_name, column_id
FROM qtab t
JOIN all_tab_columns c USING (owner, table_name)
WHERE c.nullable = 'N' -- protected by NOT NULL constraint
OR c.num_nulls = 0 -- never NULL
OR c.num_nulls < t.num_rows -- at least 1 row is NOT NULL
)
)
SELECT 'SELECT '||LISTAGG(column_name,',') WITHIN GROUP (ORDER BY column_id)||
' FROM '||owner||'.'||table_name||';' AS my_query
FROM qcol
GROUP BY owner, table_name;
This will output a query like
SELECT col1, col3, col4, col5 FROM myschema.mytable;
This query can now be executed to show the column values.

Oracle Pattern matching in group by clause

H,
How to use Pattern Matching function in "group By" clause.
Below is the Data
emp_name transaction_id
John 1001
John= 1002
Peter 1003
I want to group by based on emp_name. Here 'John' and 'John=' both are same employee. I want to ignore if the employee name has '=' sign at the end of the column.
Expected Result:
Emp_name countt
John 2
Peter 1
replace works fine and is fast. But since you asked for pattern matching, here is an answer with a pattern:
SELECT regexp_replace(emp_name, '=$', ''), count(*) AS countt
FROM employees
GROUP BY regexp_replace(emp_name, '=$', '');
A simple case statement replacing only the right most = if one exists.
SELECT case when right(emp_name,1) = '=' then left(emp_Name,len(emp_name-1))
else emp_name end as EmpName, count(Transaction_ID) countt
FROM dataTable
GROUP BY case when right(emp_name,1) = '=' then left(emp_Name,len(emp_name-1))
else emp_name end
select
replace (emp_name, '=', '') as emp_name,
count (*) as countt
from employees
group by replace (emp_name, '=', '')
Edit, since you said the name can contain an =
select
case
when emp_name like '%='
then substr (emp_name, 1, length (emp_name) - 1)
else emp_name
end as emp_name,
count (1) as countt
from employees
group by
case
when emp_name like '%='
then substr (emp_name, 1, length (emp_name) - 1)
else emp_name
end

INSERT ALL with conditions PL/SQL

I'm trying to do is write an INSERT statement with three different conditions.
Here is what I have made so far (but this code gets an ORA-00913 too many values error):
INSERT ALL
WHEN SALARY > 20000 THEN
INTO SPECIAL_SAL13(EMPLOYEE_ID,HIRE_DATE,MANAGER_ID,SALARY)
WHEN SALARY <= 20000 THEN
INTO SAL_HISTORY13(EMPLOYEE_ID,SALARY)
WHEN SALARY <= 20000 THEN
INTO MGR_HISTORY13(EMPLOYEE_ID,MANAGER_ID,SALARY)
SELECT EMPLOYEE_ID,HIRE_DATE,MANAGER_ID,SALARY
FROM EMPLOYEES
WHERE EMPLOYEE_ID < 125
try
INSERT ALL
WHEN SALARY > 20000 THEN
INTO SPECIAL_SAL13(EMPLOYEE_ID,HIRE_DATE,MANAGER_ID,SALARY)
VALUES(EMPLOYEE_ID,HIRE_DATE,MANAGER_ID,SALARY)
WHEN SALARY <= 20000 THEN
INTO SAL_HISTORY13(EMPLOYEE_ID,SALARY)
VALUES(EMPLOYEE_ID,SALARY)
WHEN SALARY <= 20000 THEN
INTO MGR_HISTORY13(EMPLOYEE_ID,MANAGER_ID,SALARY)
VALUES(EMPLOYEE_ID,MANAGER_ID,SALARY)
SELECT EMPLOYEE_ID,HIRE_DATE,MANAGER_ID,SALARY
FROM EMPLOYEES
WHERE EMPLOYEE_ID < 125
For reference see here.

Resources