SQL analytic ORACLE Converting rows into columns - sql

I have a table structue which has 2 columns as mentioned below
Column_name old Value New_Value
:--------- :------- :---------
Name NULL John
Age NULL 45
Status Active Inactive
I need a output like
John Name
45 Age
Inactive Status
Could you please help me out here.

Looks like a NVL to me ... Sample data in lines #1 - 5; query that does it begins at line #6.
SQL> with test (column_name, old_value, new_value) as
2 (select 'Name' , null , 'John' from dual union all
3 select 'Age' , null , '45' from dual union all
4 select 'Status', 'Active', 'Inactive' from dual
5 )
6 select nvl(new_value, old_value) value,
7 column_name
8 from test;
VALUE COLUMN
-------- ------
John Name
45 Age
Inactive Status
SQL>

Related

I want to get NULL when the string in my column is not available How can I achieve this using SQL?

Column
aaa-xyz-bbb
xyz-mmm-ooo
aaa-ttt-eee
How to achieve this in Oracle sql
Out put
xyz
xyz
Null
One option is to use instr function:
Sample data:
SQL> with test (col) as
2 (select 'aaa-xyz-bbb' from dual union all
3 select 'xyz-mmm-ooo' from dual union all
4 select 'aaa-ttt-eee' from dual
5 )
Query:
6 select col,
7 case when instr('-' || col || '-', '-xyz-') > 0 then 'xyz'
8 else 'Null'
9 end result
10 from test;
COL RESULT
----------- ----------
aaa-xyz-bbb xyz
xyz-mmm-ooo xyz
aaa-ttt-eee Null
SQL>

Formatting the output of SQL query to display multiple row in a single row [duplicate]

This question already has answers here:
Oracle SQL pivot query
(4 answers)
Closed 7 months ago.
I am trying to restructure the way the data is displayed
I have a table with the following structure
ID Key Value
1 OrgName Google
1 email John.Smith#gmail.com
1 Status active
1 givenName John
1 sn Smith
1 userName JSmith
2 OrgName Yahoo
2 email Paul.Jonesh#yahoo.com
2 Status active
2 givenName Paul
2 sn Jones
2 userName PJones
How can I write an SQL query that will return it in this format
ID givenName sn
1 John Smith
2 Paul Jones
Aggregate, conditionally (is one option):
Sample data:
SQL> with test (id, key, value) as
2 (select 1, 'OrgName' , 'Google' from dual union all
3 select 1, 'givenName', 'John' from dual union all
4 select 1, 'sn' , 'Smith' from dual union all
5 select 2, 'OrgName' , 'Yahoo' from dual union all
6 select 2, 'givenName', 'Paul' from dual union all
7 select 2, 'sn' , 'Jones' from dual
8 )
Query begins here:
9 select id,
10 max(case when key = 'givenName' then value end) as givenName,
11 max(case when key = 'sn' then value end) as sn
12 from test
13 group by id;
ID GIVENN SN
---------- ------ ------
1 John Smith
2 Paul Jones
SQL>
Pivot functionality in Oracle can be used here. The query will look like
select * from (
select key, id, value from test
) pivot (
max(value) for key in ('OrgName', 'email', 'Status', 'givenName', 'sn', 'userName')
);
Similar question was answered here using pivot. It contains more details and explanation. Hope it helps!

Need Oracle Query Tune for order by

I have two tables:
METHOD_TYPES
---- ----------------
ID Methods_Type
---- ----------------
1 public
2 ALL_Methods
3 private1235678
4 social
METHOD_TABLE
-------- ----------------- ----------
Ser_ID Ser_Method_Type Emp_Name
-------- ----------------- ----------
1 (null) AAAA
2 (null) BBBB
3 All_Methods Rama
4 social Raja
5 private12345678 Rakesh
I used the below query for the ORDER BY:
SELECT SUBSTR(Methods_Type, 1, 10) AS disMisType
FROM METHOD_TABLE MET
LEFT JOIN METHOD_TYPES TRMT
ON MET.Ser_Method_Type = TRMT.Methods_Type
ORDER BY (NLSSORT(MET.Ser_Method_Type, 'NLS_SORT=binary_ai')) DESC NULLS FIRST;
OUTPUT:
(null)
All_Methods
(null)
social
private12345678
But I need to order all the nulls first.
Kindly provide the exact query.
Using the data you provided - and adding in the extra columns, I get:
with method_types as (select 1 id, 'public' methods_type from dual union all
select 2 id, 'ALL_Methods' methods_type from dual union all
select 3 id, 'private1235678' methods_type from dual union all
select 4 id, 'social' methods_type from dual),
method_table as (select 1 ser_id, null ser_method_type, 'AAAA' emp_name from dual union all
select 2 ser_id, null ser_method_type, 'BBBB' emp_name from dual union all
select 3 ser_id, 'All_Methods' ser_method_type, 'Rama' emp_name from dual union all
select 4 ser_id, 'social' ser_method_type, 'Raja' emp_name from dual union all
select 5 ser_id, 'private12345678' ser_method_type, 'Rakesh' emp_name from dual)
select substr(trmt.methods_type,1,10) as dismistype,
met.*,
trmt.*
from method_table met
left join method_types trmt on (met.ser_method_type = trmt.methods_type)
order by (nlssort(met.ser_method_type, 'NLS_SORT=binary_ai')) desc nulls first;
DISMISTYPE SER_ID SER_METHOD_TYPE EMP_NAME ID METHODS_TYPE
------------------------------ ---------- --------------- -------- ---------- --------------
1 AAAA
2 BBBB
social 4 social Raja 4 social
5 private12345678 Rakesh
3 All_Methods Rama
which is not what your expected output shows, but it does maybe explain why you see nulls apparently out of order in your results - you're selecting the trmt.methods_type column, but ordering by the met.ser_method_type column. If there aren't any rows in the method_types table matching those in the method_table, then of course you will see nulls, but because there IS a value in the method_table, they may well be displayed after rows that do have a value.
Perhaps all you need to do is to change the column being selected
from substr(trmt.methods_type,1,10)
to substr(met.ser_method_type,1,10)
or change the order clause
from nlssort(met.ser_method_type, 'NLS_SORT=binary_ai')
to nlssort(trmt.methods_type, 'NLS_SORT=binary_ai')
I'm not sure why your query is not working, but you can have a more explicit order by:
ORDER BY (CASE WHEN MET.Ser_Method_Type IS NULL THEN 1 ELSE 2 END),
NLSSORT(MET.Ser_Method_Type, 'NLS_SORT=binary_ai') DESC
You can create a CASE Column only for order:
select SUBSTR(Methods_Type,1,10)AS disMisType,
SUBSTR(CASE WHEN Methods_Type IS NULL THEN '0' ELSE Methods_Type END ,1,10) AS disMisTypeORDER
FROM METHOD_TABLE MET
LEFT JOIN METHOD_TYPES TRMT
ON MET.Ser_Method_Type = TRMT.Methods_Type
ORDER BY disMisTypeORDER

How to check a value exists in an integer array - SQL case statement

I'm looking for a solution to check the existence of a value in an array, so that I need to toggle a column based on that values.
Here is the table structure
ID Name
-------------------
1 Alex
2 John
3 Joel
4 Philip
5 Susan
6 Tim
7 Jerry
-------------------------
So the condition is I need all rows but there will be third column which will be based on an existence logic. That is the third column is T if the ID exists in (1,5,7) otherwise the column will be W. So the result will be something like this
ID Name status
-------------------
1 Alex T
2 John W
3 Joel W
4 Philip W
5 Susan T
6 Tim W
7 Jerry T
-------------------------
Thanks
select *, case when id in (1,5,7)
then 'T'
else 'W'
end as status
from your_table
This query will be helpful.
DECLARE #Test Table
(
Id Integer,
Name VARCHAR(10)
)
INSERT INTO #Test
SELECT 1, 'AAA' UNION ALL
SELECT 2, 'BBB' UNION ALL
SELECT 3, 'CCC' UNION ALL
SELECT 4, 'DDD' UNION ALL
SELECT 5, 'EEEE' UNION ALL
SELECT 6, 'FFFF' UNION ALL
SELECT 7, 'RRRR'
select *, CASE WHEN Id iN (1,5,7)
THEN 'T'
ELSE 'D'
END AS STATUS
FROM #Test

SQL find nearest number

Say I have a table like the following (I'm on Oracle 10g btw)
NAME VALUE
------ ------
BOB 1
BOB 2
BOB 4
SUZY 1
SUZY 2
SUZY 3
How can I select all rows where value is closest to, but not greater than, a given number. For example if I want to find all the rows where value is closest to 3 I would get:
NAME VALUE
------ ------
BOB 2
SUZY 3
This seems like it should be simple... but I'm having no luck.
Thanks!
SELECT name, max(value)
FROM tbl
WHERE value <= 3
GROUP BY name
This works (SQLFiddle demo):
SELECT name, max(value)
FROM mytable
WHERE value <= 3
GROUP BY name
Based on hagensofts answer:
SELECT name, max(value)
FROM tbl
WHERE value <= 3 AND ROWNUM <=2
GROUP BY name
With ROWNUM you can limit the output rows, so if you want 2 row, then you can limit the rownum.
WITH v AS (
SELECT 'BOB' NAME, 1 value FROM dual
UNION ALL
SELECT 'BOB', 2 FROM dual
UNION ALL
SELECT 'BOB', 4 FROM dual
UNION ALL
SELECT 'SUZY', 1 FROM dual
UNION ALL
SELECT 'SUZY', 2 FROM dual
UNION ALL
SELECT 'SUZY', 3 FROM dual
)
SELECT *
FROM v
WHERE (name, value) IN (SELECT name, MAX(value)
FROM v
WHERE value <= :num
GROUP BY name)
;