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
)
Related
If I am interested in selecting records that have the largest value in each group of duplicate records (and some general conditions), I normally do this with the following SQL code:
select a.id, a.col2, b.col3
from (select id, col2, col3,
rank() over (partition by id order by col2 desc, col3 desc) as r1 from my_table where col2 > 5 and col3 > 5) a
where a.r1 =1
I am interested in learning alternate ways to do this.
Are there other popular ways to do this in (netezza) SQL?
Thank you!
One way to do it is with NOT EXISTS:
SELECT t1.id, t1.col2, t1.col3
FROM my_table t1
WHERE t1.col2 > 5 AND t1.col3 > 5
AND NOT EXISTS (
SELECT 1
FROM my_table t2
WHERE t2.id = t1.id AND t2.col2 > 5 AND t2.col3 > 5
AND (t2.col2 > t1.col2 OR (t2.col2 = t1.col2 AND t2.col3 > t1.col3))
);
Or, if you use a CTE to preselect from the table:
WITH cte AS (
SELECT id, col2, col3
FROM my_table
WHERE col2 > 5 AND col3 > 5
)
SELECT c1.*
FROM cte c1
WHERE NOT EXISTS (
SELECT 1
FROM cte c2
WHERE c2.id = c1.id
AND (c2.col2 > c1.col2 OR (c2.col2 = c1.col2 AND c2.col3 > c1.col3))
);
Depending on the requirement, the WHERE clause inside the subquery may be a lot more complex. This is one of the reasons that, if you can, you should use a window function.
when i run this query returns all rows that their id exist in select from table2
SELECT * FROM table1 WHERE id in (
SELECT id FROM table2 where name ='aaa'
)
but when i add limit or between to second select :
SELECT * FROM table1 WHERE id in (
SELECT id FROM table2 where name ='aaa' limit 4
)
returns this error :
This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
You are using LIMIT without an ORDER BY. This is generally not recommended because that returns an arbitrary set of rows -- and those can change from one execution to another.
You can convert this to a JOIN -- fortunately. If id is not duplicated in table2:
SELECT t1.*
FROM table1 t1 JOIN
(SELECT t2.id
FROM table2 t2
WHERE t2.name = 'aaa'
LIMIT 4
) t2
USING (id);
If id can be duplicated in table2, then:
SELECT t1.*
FROM table1 t1 JOIN
(SELECT DISTINCT t2.id
FROM table2 t2
WHERE t2.name = 'aaa'
LIMIT 4
) t2
USING (id);
Another fun way uses LIMIT:
SELECT t1.*
FROM table1 t1
WHERE id <= ANY (SELECT t2.id
FROM table2
WHERE t2.name = 'aaa'
ORDER BY t2.id
LIMIT 1 OFFSET 3
);
LIMIT is allowed in a scalar subquery.
You can use an analytic function such as ROW_NUMBER() in order to return one row from the subquery. I suppose, this way no problem would occur like raising too many rows issue :
SELECT * FROM
(
SELECT t1.*,
ROW_NUMBER() OVER (ORDER BY t2.id DESC) AS rn
FROM table1 t1
JOIN table2 t2 ON t2.id = t1.id
WHERE t2.name ='aaa'
) t
WHERE rn = 1
P.S.: Btw, id columns are expected to be primary keys of your tables, aren't they ?
Update ( depending on your need in the comment ) Consider using :
SELECT * FROM
(
SELECT j.*,
ROW_NUMBER() OVER (ORDER BY j.id DESC) AS rn2
FROM job_forum j
CROSS JOIN
( SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY t2.id ORDER BY t2.id DESC) AS rn1
FROM table2 t2
WHERE t2.name ='aaa'
AND t2.id = j.id ) t2
WHERE rn1 = 1
) jj
WHERE rn2 <= 10
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 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
Given two tables (count(Table1) <= count(Table2)):
Table1:
record-1
record-2
...
record-k
Table2:
promo-1
promo-2
...
promo-j
Is it possible to join them into the following table? I.e. assign each entry in Table1 some entry in Table2, but that no two entries in Table1 would correspond to the same entry in Table2.
Result:
record-1 promo-i1
record-2 promo-i2
...
record-n promo-in
You could create a fake key using the rownum pseudo-column, and join according to that:
SELECT t1.col1, t2.col2
FROM (SELECT col1, ROWNUM AS rn
FROM table1
ORDER BY col1) t1
JOIN (SELECT col2, ROWNUM AS rn
FROM table2
ORDER BY col2) t2 ON t1.rn = t2.rn
EDIT:
A slightly "clunkier", yet more ANSI-friendly approach would be to use the ROW_NUMBER() window function:
SELECT t1.col1, t2.col2
FROM (SELECT col1, ROW_NUMBER() OVER (ORDER BY col1) AS rn
FROM table1) t1
JOIN (SELECT col2, ROW_NUMBER() OVER (ORDER BY col2) AS rn
FROM table2) t2 ON t1.rn = t2.rn