Remove duplicate based on condition - sql

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.

Related

Union in sql with default return

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.

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);

if-else clause in SQL

Is there any way to create query for such request without PL/SQL:
if (select count(column) from table = 0)
then select column1, column2, column 3 from table where condition1
else select column1, column2, column 3 from table where condition2
select column1, column2, column3
from table
where (condition1 and (select count(column) from table) = 0)
or (condition2 and (select count(column) from table) != 0)
SQL = SELECT QUERY;
if(Column != 0)
{
SELECT QUERY;
}
if(Column2 != 0)
{
SELECT QUERY;
}
It should work when you don't add an else statement.
You could use two LEFT JOINS and COALESCE (here, I use column1 > 2 / column1 <=2 as condition1 and condition2):
with
v1 as (select count(column4) as c4_cnt from table1),
v_cond1 as (select column1, column2, column3 from table1 where column1 > 2),
v_cond2 as (select column1, column2, column3 from table1 where column1 <= 2)
select
v1.*,
coalesce(v_cond1.column1, v_cond2.column1) as column1,
coalesce(v_cond1.column2, v_cond2.column2) as column2,
coalesce(v_cond1.column3, v_cond2.column3) as column3
from v1
left join v_cond1 on v1.c4_cnt = 0
left join v_cond2 on v1.c4_cnt != 0

How to copy one table to another

I want to copy the contents of table1 into table2, but it's not a straight copy, as table2 contains more columns than table 1. The structure is similar to this:
Table1
{
column2
column4
column6
}
Table2
{
column1
column2
column3
column4
column5
column6
}
What I want to do is add every row from table1 to table2, and set default values for the missing columns. Any help would be appreciated.
You can just do an
INSERT INTO xxx
SELECT yyy
And in the select clause, put default values.
INSERT INTO Table2(column1, column2, column3, column4, column5, column6)
SELECT 'horse', column2, 2, column4, 'what ever I want', column6
FROM Table1
So int Table2, all column1 will have 'horse' value.
All column3 will have 2.
Etc.
use INSERT..INTO SELECT statement
INSERT INTO table2 (column2, column4, column6)
SELECT column2, column4, column6
FROM table1
so in this case, columns: column1, column2, column3 will have null values. or whatever default you have set.
Not great at SQL but something like this:
INSERT INTO [Table1] (column2, column4, column6) SELECT (column1, column2, column3) FROM [Table2]
Hope this helps. Link that may be useful, http://www.blackwasp.co.uk/SQLSelectInsert.aspx
vote me I need points :P
Please try
INSERT INTO
Table2 (
column1,
column2,
column3,
column4,
column5,
column6,
)
SELECT
'StaticValue1',
column2,
'StaticValue2'
column4,
'StaticValue3'
column6,
FROM
Table1
To copy a full table into a new table:
SELECT * INTO table2 FROM table1;
http://www.w3schools.com/sql/sql_select_into.asp
To copy a table into an existing table:
INSERT INTO table2
SELECT * FROM table1;
http://www.w3schools.com/sql/sql_insert_into_select.asp
insert into TABLE2
select null colum1, column2,null colum3,column4,null colum5,column6
from((
Select TABLE1.column2, TABLE1.column4, TABLE1.column6
from TABLE1, TABLE2
where TABLE1.primarykey=TABLE2.primarykey))

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