I want to find the entries where col2 record present in col1.
Table:
CREATE TABLE Test_Table
(
Col1 int,
Col2 int
);
Entries:
INSERT INTO Test_Table VALUES(111,112),
(112,113),
(114,115),
(116,117),
(117,118),
(118,119);
Expected Result:
Col1 Col2
-------------
111 112
112 113
116 117
117 118
118 119
Note: Record 114,115 not displyed because 115 is not present in col1.
My try:
WITH CTE1
AS
(
SELECT Col1, Col2
FROM Test_Table
),
CTE2
AS
(
SELECT t.Col1, t.Col2
FROM Test_Table t
INNER JOIN CTE1 s1
ON s1.Col2 = t.Col1
OR s1.Col2 = t.Col2
)
SELECT DISTINCT * FROM CTE2;
But getting all records.
This might also work
select t.*
from Test_Table t
where exists (select 1
from test_table t2
where t2.col1 = t.col2 or t2.Col2 = t.Col1
)
I think this is what you want.
select t.*
from #test_table t
where exists (select 1
from #test_table t2
where t2.col1 = t.col2
)
or exists (select 1
from #test_table t3
where t3.col2 = t.col1
);
I think you just want exists:
select tt.*
from test_table tt
where exists (select 1
from test_table tt2
where tt2.col1 = tt.col2
);
Using CROSS JOIN:
select t1.* from test_table t1 CROSS JOIN test_table t2
on t1.col1 = t2.col2
UNION
select t1.* from test_table t1 CROSS JOIN test_table t2
on t1.col2 = t2.col1
Based on your comments, I suspect you want either col1/col2 to exist at another row's either col1/col2
select tt.*
from test_table tt
where exists (select 1
from test_table tt2
where -- Ensure not same row
(tt2.col1 <> tt.col1 or tt2.col2 <> tt.col2)
and -- Ensure at least one match
(tt2.col1 = tt.col1 or tt2.col1 = tt.col2 or tt2.col2 = tt.col1 or tt2.col2 = tt.col2)
);
select t1.* from Test_Table t1 left join Test_Table t2 on t2.Col1=t1.Col2 where t2.Col2 is not null
union
select t1.* from Test_Table t1 left join Test_Table t2 on t2.Col2=t1.Col1 where t2.Col1 is not null
Related
Let's say I have two tables t1 and t2.
t1 has two integer cols col1 (primary) and col2
t2 has two cols a foreign key of t1.col1 and t2.col2
I want to do the following
Retrieve only the records where t1.col2 is unique OR if t1.col2 is duplicate only those if t2.col2 is not null.
Insert the above records into another summary table, let's say t3
This is what I tried:
insert into t3 (col1,col2)
select col1, col2
from t1
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
union
select col1, col2
from t1, t2
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
and t2.col2 is not null;
While the 'union qry' works on its own, the insert is not happening.
Any ideas or any other efficient way to achieve this please
You can select the records you want using:
select t1.*
from (select t1.*, count(*) over (partition by col2) as cnt
from t1
) t1
where cnt = 1 or
exists (select 1 from t2.col1 = t1.col1 and t2.col2 is null);
The rest is just an insert.
I have the following 2 table:
Col1|Col2|Col3
Val1 T1
Val2 T2
Col1|Col2|Col3|Col4
Val1 test 1
Val1 test 2
Val1 T1 3
Val2 test 1
Val2 T2 2
I need to update the values for Col3 of Table 1 with the summation of Col3 of table 2 until Col2 of Table 2 reaches the value from Col2 of Table 1. So, Table 1 should look like this:
Col1|Col2|Col3
Val1 T1 6
Val2 T2 3
So, it adds up 1+2+3 = 6 for T1 and 1+2 = 3 for T2.
Basically, the Col1 for both tables will be the key. I am using MSSQL2008 server. I tried to do this with Cursor but no luck so far.
Please note, the order by column in Table2 is a Date column (Column4). It is ordered by Desc.
You can get this by GROUP BY:
CREATE TABLE #Table1(Col1 VARCHAR(10),Col2 VARCHAR(10),Col3 INT)
CREATE TABLE #Table2(Col1 VARCHAR(10),Col2 VARCHAR(10),Col3 INT,Col4 DATETIME)
INSERT INTO #Table1 VALUES('Val1','T1',0)
INSERT INTO #Table1 VALUES('Val2','T2',0)
INSERT INTO #Table2 VALUES('Val1','test',1,GETDATE())
INSERT INTO #Table2 VALUES('Val1','test',2,GETDATE()-1)
INSERT INTO #Table2 VALUES('Val1','T1',3,GETDATE()-2)
INSERT INTO #Table2 VALUES('Val1','test',4,GETDATE()-3)
INSERT INTO #Table2 VALUES('Val2','test',1,GETDATE())
INSERT INTO #Table2 VALUES('Val2','T2',2,GETDATE()-1)
UPDATE T1
SET T1.Col3 = T2.SummationValue
FROM #Table1 T1
JOIN (
SELECT T2.Col1,T2.Col2,SUM(T2.Col3) OVER(PARTITION BY T2.Col1 ORDER BY Col4 DESC)SummationValue
FROM #Table2 T2
JOIN #Table1 T1 ON T2.Col1 = T1.Col1
)T2
ON T1.Col1 = T2.Col1 AND T1.Col2 = T2.Col2
SELECT * FROM #Table1
DROP TABLE #Table1
DROP TABLE #Table2
OutPut:
Col1 Col2 Col3
Val1 T1 6
Val2 T2 3
SQL Fiddle
This is a bit tricky. You can get the cutoff point using a correlated subquery:
update t1
set col3 = t2.sum_col3
from t1 join
(select t2.col1, sum(t2.col3) as sum_col3
from t2
where t2.t4 >= (select tt2.t4
from t2 tt2 join
t1 tt1
on tt2.col1 = tt1.col1 and
tt2.col2 = tt1.col2
)
group by t2.col1
) t2
on t2.col1 = t1.col1;
Alternatively, you can use window functions (but not a cumulative sum):
update t1
set col3 = t2.sum_col3
from t1 join
(select t2.col1,
sum(t2.col3) as sum_col3
from (select t2.col1,
min(case when tt2.col1 = tt1.col2 then tt2.col4 end) over (partition by tt2.col1) as col4_match
from t2 tt2 join
t1 tt1
on tt2.col1 = tt1.col1
) t2
where col4 >= col4_match
group by t2.col1
) t2
on t2.col1 = t1.col1
A sample table with two column and I need to compare the column 1 and column 2 to the same table records and need to remove the column 1 + column 2 = column 2+column 1.
I tried to do self join and case condition. But its not working
If I understand correctly, you can run a simple select like this if you have all reversed pairs in the table:
select col1, col2
from t
where col1 < col2;
If you have some singletons, then:
select col1, col2
from t
where col1 < col2 or
(col1 > col2 and
not exists (select 1
from t t2
where t2.col1 = t.col2 and
t2.col2 = t.col1
)
);
You can use the except operator.
"EXCEPT returns distinct rows from the left input query that aren't output by the right input query."
SELECT C1, C2 FROM table
Except
SELECT C2, C1 FROM table
Example with your given data set : dbfiddle
I am posting the answer based on oracle database and also the columns are string/varchar:
delete from table where rowid in (
select rowid from table
where column1 || column2 =column2 || column1 )
Feel free to provide more input and we can tweak the answer.
Okay. There might be a simpler way of doing this but this might work as well. {table} is to be replaced with your table name.
;with orderedtable as (select t1.col1, t1.col2, ROW_NUMBER() OVER(ORDER BY t1.col1, t1.col2 ASC) AS rownum
from (select distinct t2.col1, t2.col2 from {table} t2) as t1)
select f1.col1, f1.col2
from orderedtable f1
left join orderedtable f2 on f1.col1 = f2.col2 and f1.col2 = f2.col1 and f1.rownum < f2.rownum
where f2.rownum is null
The SQL below will get the reversed col1 and col2 rows:
select
distinct t2.col1,t1.col2
from
table t1
join
table t2 on t1.col1 = t2.col2 and t1.col2 = t2.col1
And when we get these reversed rows, we can except them with the left join clause, the complete SQL is:
select
t.col1,t.col2
from
table t
left join
(
select
distinct t2.col1,t1.col2
from
table t1
join
table t2 on t1.col1 = t2.col2 and t1.col2 = t2.col1
) tmp on t.col1 = tmp.col1 and t.col2 = tmp.col2
where
tmp.col1 is null
Is it clear?
I have table like below
the result set should contain 4,5 since it has count of (c2) and (c3) >1
You can use exists :
select t.*
from table t
where exists (select 1 from table t1 where t1.col2 = t.col2 and t1.col1 <> t.col1);
JOIN a subquery that returns the duplicated col2 values:
select t1.*
from tablename t1
join (select col2 from tablename
group by col2 having count(*) > 1) t2
on t1.col2 = t2.col2
I would use window functions:
select t.*
from (select t.*,
count(*) over (partition by c2) as c2_cnt,
count(*) over (partition by c3) as c3_cnt
from t
) t
where c2_cnt > 1 and c3_cnt > 1;
As you changed your requirement so i changed my query
select t1.* from table_name t1 where
exists( select 1 from table_name t2 where t2.col2=t1.col2
and t2.c3=t1.c3
group by t2.c2,t2.c3
having count(*)>1
)
We have a legacy table
create table table1 (col1 int);
insert into table1 values(1);
insert into table1 values(2);
insert into table1 values(3);
SELECT * FROM table1;
1
2
3
now it gets a new column
alter table table1 add column col2 int;
alter table table1 ADD CONSTRAINT unique1 UNIQUE (col2);
SELECT * FROM table1;
1;null
2;null
3;null
then we have another table
create table table2 (col1 int);
insert into table2 values(7);
insert into table2 values(8);
insert into table2 values(9);
SELECT * FROM table2;
7
8
9
now we want to spread the values of table 2 into table1.col2
UPDATE table1 up
SET col2 = (SELECT col1
FROM table2 t2
WHERE NOT EXISTS (SELECT 1 FROM table1 t1 WHERE t1.col2=t2.col1)
LIMIT 1);
but the update statement does not see the already updated rows
ERROR: duplicate key value violates unique constraint "unique1"
Any ideas how to do that? It would be ok, if table1 remains with some rows col2=null if table2 has less rows than table1
This seems much easier with a join:
with t2 as (
select t2.*, row_number() over (order by col1) as seqnum
from table2 t2
)
update table1 t1
set col2 = t2.col1
from t2
where t1.col1 = t2.seqnum;
If col1 in table1 is not strictly sequential, you can still do this:
with t2 as (
select t2.*, row_number() over (order by col1) as seqnum
from table2 t2
),
t1 as (
select t1.*, row_number() over (order by col1) as seqnum
from table1 t1
)
update table1 toupdate
set col2 = t2.col1
from t1 join
t2
on t1.seqnum = t2.seqnum
where toupdate.col1 = t1.col1;
i think i found a solution
WITH rownumbers AS (
SELECT col1, row_number() over (partition by 1 ORDER BY col1) FROM table1
)
UPDATE table1 up SET col2 =
(SELECT col1 FROM table2 t2 WHERE NOT EXISTS (SELECT 1 FROM table1 t1 WHERE t1.col2=t2.col1)
LIMIT 1 OFFSET (
SELECT row_number-1 FROM rownumbers WHERE col1=up.col1
)
)
any cons about it?