Union in sql with default return - sql

I have scenarios where there are multiple tables Table1, Table2, and Table3 and there are some common columns in them. Now I have to take join with tables on bases of the condition if record exists from the table than its good but if it not exist then it doesn't return any row but I have to return some default/0
select 'Section','Table1',column1, column2, column3 from table1 where column>1
union
select 'Section','Table2',column1, column2, column3 from table2 where column>3
union
select 'Section','Table3',column1, column2, column3 from table3 where column>2
suppose data doesn't exist in table 2 instead of skipping that table record should show in the result
in simple I want if the record not exist against any table it would be replaced by the below code
select 'Section','Table2',0 as column1, 0 as column2, 0 as column3
Output should be like this
Results
Section Table1 2 2022-06-12 abc
Section Table2 0 '' ''
Section Table3 3 2022-07-22 Xyz

You can use EXISTS. ie:
select 'Section','Table1',column1, column2, column3
from (values (0,0,0))
t(column1,column2,column3)
where not exists (select * from table1 where column1 > 1)
union
select 'Section','Table1',column1, column2, column3 from table1 where column1>1
union
select 'Section','Table2',column1, column2, column3
from (values (0,0,0))
t(column1,column2,column3)
where not exists (select * from table2 where column1 > 3)
union
select 'Section','Table2',column1, column2, column3 from table2 where column1>3
union
select 'Section','Table3',column1, column2, column3
from (values (0,0,0))
t(column1,column2,column3)
where not exists (select * from table3 where column1 > 2)
union
select 'Section','Table3',column1, column2, column3 from table3 where column1>2;
DBFiddle demo
It is SQL server but is valid for many databases if not all.

Related

Removing Partitioned rows from oracle sql query output

I have below query
SELECT ROW_NUMBER() OVER ( PARTITION BY COLUMN1, COLUMN2, COLUMN3 ORDER BY COLUMN1, COLUMN2) AS ROW_NUM, COLUMN1, COLUMN2, COLUMN3
FROM (SUBQUERY)
GROUP BY COLUMN1, COLUMN2, COLUMN3
OUTPUT of above query:-
I need to perform something equivalent to
IF (COLUMN2 == 'PQR' AND COLUMN3 IS NOT NULL)
THEN
"Delete whole partition from output having value A3 in column1"
Explaination:-
If COLUMN2 is having value PQR and COLUMN3 is having any DATE_TIME (i.e. NOT NULL) then all the corresponding COLUMN1 value should not be present in output of query.
OUTPUT required is:-
I tried to be as clear as I can be. Let me know if I need to clarify my question more.
NOTE:- I want to remove those rows only from output of the query not from actual table.
If you are doing this using a subquery, then you might want to use window functions:
SELECT s.*
FROM (SELECT ROW_NUMBER() OVER ( PARTITION BY COLUMN1, COLUMN2, COLUMN3 ORDER BY COLUMN1, COLUMN2) AS ROW_NUM,
COLUMN1, COLUMN2, COLUMN3,
COUNT(CASE WHEN COLUMN2 = 'PQR' THEN COLUMN3 END) OVER (PARTITION BY COLUMN1) as cnt
FROM (SUBQUERY)
GROUP BY COLUMN1, COLUMN2, COLUMN3
) s
WHERE cnt = 0;
This counts the number of COLUMN3 values where COLUMN2 = 'PQR' over all each COLUMN1. It then returns only the rows where this count is 0.
The advantage of this approach is that it only evaluates the subquery once -- that can be a performance win (over NOT EXISTS) if it is complicated.
If you want a select query then you can use NOT EXISTS:
SELECT * FROM YOUR_TABLE T1
WHERE NOT EXISTS (SELECT 1 FROM YOUR_TABLE T2
WHERE T1.COLUMN1 = T2.COLUMN1
AND T2.COLUMN2 = 'PQR' AND T2.COLUMN3 IS NOT NULL);
You can use the EXISTS to delete such records as follows:
DELETE FROM YOUR_TABLE T1
WHERE EXISTS (SELECT 1 FROM YOUR_TABLE T2
WHERE T1.COLUMN1 = T2.COLUMN1
AND T2.COLUMN2 = 'PQR' AND T2.COLUMN3 IS NOT NULL);

How to combine multiple columns into one column?

I'm writing a query and want the results in one column
My current results return like this
Column1 Column2 column3
1 A CAT
I want the results to return like this
Column1
1
A
CAT
SELECT Column1 FROM TableName
UNION ALL
SELECT Column2 FROM TableName
UNION ALL
SELECT Column3 FROM TableName
If you don't want duplicate values, use UNION instead of UNION ALL.
You can also do this using UNPIVOT operator
SELECT Column123
FROM
(
SELECT Column1, Column2, Column3
FROM TableName
) AS tmp
UNPIVOT
(
Column123 FOR ColumnAll IN (Column1, Column2, Column3)
) AS unpvt;
https://www.w3schools.com/sql/sql_union.asp
https://www.mssqltips.com/sqlservertip/3000/use-sql-servers-unpivot-operator-to-help-normalize-output/
The answer is.. it depends..
If the number of columns are unknown.. then use unpivot as UZI has suggested
if you know all columns and is a small finite set..
you can simply go
Select
column1
from table
union all
select column2
from table
union all
select column3
from table
The Cartesian product of the T table with derived table of 3 rows.(each row of #t is presented 3 times, for а=1 and а=2 and а=3). For the first case we take value from Column1,
and for the second - from Column2 and for the Third - from Column3.
Here, certainly, there is both union and join but, in my opinion, the title's question means single scanning the table.
CREATE TABLE #t (Column1 NVARCHAR(25),Column2 NVARCHAR(25), column3 NVARCHAR(25))
INSERT INTO #t
SELECT '1','A','CAT'
SELECT
CASE a WHEN 1 THEN Column1 WHEN 2 THEN Column2 ELSE column3 END col
FROM #t, (SELECT 1 a UNION ALL SELECT 2 UNION ALL SELECT 3) B
DROP TABLE #t

SQL comparing all values in a many-one table

I have a table as follows
column1 column2
a 1
a 2
b 2
I need to write an sql query that will go through the table and return me all column 2 values that have both a and b in column 1.
Try this:
SELECT column2
FROM mytable
WHERE column1 IN ('a', 'b')
GROUP BY column2
HAVING COUNT(DISTINCT column1) = 2
Try this:
SELECT column1, column2, ROW_NUMBER()OVER(PARTITION BY column1 Order by column1 )as rowCounts into #tmp2
FROM #tmp
SELECT column2 FROM #tmp2 WHERE rowCounts = 1

Remove duplicate based on condition

My table value:
COLUMN1 COLUMN2 COLUMN3
WF1 Email 1640
WF1 Email 1641
WF1 Email N/A
WF3 Email N/A
Expected Result:
COLUMN1 COLUMN2 COLUMN3
WF1 Email 1640
WF3 Email N/A
I need to retrieve all records which column2 = 'Email' and if column1 contains duplicate value, i have to choose the record which column3 <> 'N/A'.
I read tutorial about partition by but still not sure how to get the result.
Any help is appreciated.
CREATE TABLE TABLE1
(
COLUMN1 varchar2(20),
COLUMN2 varchar2(20),
COLUMN3 varchar2(20)
);
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3)
VALUES
('WF1', 'Email', '1640');
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3)
VALUES
('WF1', 'Email', '1641');
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3)
VALUES
('WF1', 'Email', 'N/A');
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3)
VALUES
('WF3', 'Email', 'N/A');
Try something like this:
SELECT column1, column2, column3
from(
SELECT column1, column2, column3,
row_number() over (partition BY column1, column2 ORDER BY CASE WHEN column3 = 'N/A' THEN 999999999 ELSE to_number(column3) END ) rn
FROM table1)
WHERE rn = 1
Here is a sqlfiddle
select column1,column2,max(case when column3 = 'N/A' then '0' else column3 end) column3
from table1
group by column1,column2;
If column1 can be not unique in the result:
select column1, column3 from table1 t1
where column3 != 'N/A' or
column3 = 'N/A' and not exists
(select * from table1 t2
where t2.column1 = t1.column1 and t2.column3 != 'N/A')
If column1 must be unique in the result:
select column1, column3 from table1 t1
where column3 != 'N/A' and not exists
(select * from table1 t2
where t2.column1 = t1.column1 and t2.column3 != 'N/A' and
to_number(t2.column3, '9999') > to_number(t1.column3, '9999')
) union
select column1, column3 from table1 t1
where column3 = 'N/A' and not exists
(select * from table1 t2 where t2.column1 = t1.column1 and t2.column3 != 'N/A')
Note that we use union instead of union all.

How to access the value of a function generated column in SQL

I have the following SQL
select count(*) col, column1, column2, column3 from TempTable
group by column1, column2, column3
order by 1 desc
so the column generated by the count will return a number and there are 17 rows that do not have the number 1 (duplicate rows as columns 1, 2 and 3 are primary keys) and i want to delete any that have the count greater than 1?
You can use the having-clause:
select count(*) col, column1, column2, column3
from TempTable group by column1, column2, column3
having count(*) > 1
order by 1 desc
To delete:
delete tt
from TempTable tt
inner join (select count(*) col, column1, column2, column3
from TempTable group by column1, column2, column3
having count(*) > 1) tmp
on tmp.column1 = tt.column1
and tmp.column2 = tt.column2
and tmp.column3 = tt.column3
First you insert the data in temporary table:
select count(*) col, column1, column2, column3
into #temp
from TempTable group by column1, column2, column3 order by 1 desc
Then, you delete the data, and insert it from the #temp table:
delete from TempTable
go
insert into TempTable select column1, column2, column3 from #temp
go