I have a structure like this:
col0 col1 col2 col3
1 1 1 1
1 1 1 2
1 1 1 3
1 2 1 1
1 2 3 1
2 3 4 5
2 3 4 9
I now want to select all rows, that match other rows on the first three columns, so the result of this query using the sample data would be:
col0 col1 col2 col3
1 1 1 1
1 1 1 2
1 1 1 3
2 3 4 5
2 3 4 9
How can I achieve this, I'm kinda stuck at the early beginning...
Thanks in advance! Alex
Update: Clearified the question. Thanks Erwin.
4 Answers 4
SELECT
col0
,col1
,col2
,col3
FROM
foo
WHERE
col0 = col1
and col0 = col2;
-
Well it does not do it, unfortunately.dArignac– dArignac2013年08月03日 09:36:24 +00:00Commented Aug 3, 2013 at 9:36
-
3@MikeFal the OP has edited the question so he needs something else, not the first description (which you had answered.)ypercubeᵀᴹ– ypercubeᵀᴹ2013年08月03日 09:38:56 +00:00Commented Aug 3, 2013 at 9:38
I somehow managed to find a solution, though I do not know if there is a more performant variant:
select
distinct a.col0, a.col1, a.col2, a.col3
from foo a, foo b
where
a.col0 = b.col0 and
a.col1 = b.col1 and
a.col2 = b.col2 and
a.col3 != b.col3
order by
a.col0,
a.col1,
a.col2;
We have to find all touples (col0, col1, col3) that occour at least twice and then get all rows that match the tuples.
Solution A: col0, col1 and col2 do not contain any NULLs
SELECT * FROM
foo
WHERE (col0, col1, col2) IN (
SELECT col0, col1, col2
FROM foo
GROUP BY 1,2,3
HAVING count(*)>1
);
Solution B: NULLs are allowed:
SELECT f.*
FROM foo f
JOIN (
SELECT col0, col1, col2
FROM foo
GROUP BY 1,2,3
HAVING count(*)>1
) q
ON (
f.col0 IS NOT DISTINCT FROM q.col0
AND f.col1 IS NOT DISTINCT FROM q.col1
AND f.col2 IS NOT DISTINCT FROM q.col2
);
I find common table expressions (CTEs) to be tremendously helpful in breaking a query like this down into blocks that are easier for me wrap my brain around.
Here is your problem using a CTE:
WITH cte AS (
SELECT DISTINCT col0, col1, col2
FROM foo)
SELECT foo.*
FROM foo
INNER JOIN cte
ON cte.col0 = foo.col0
AND cte.col1 = foo.col1
AND cte.col2 = foo.col2
Here's the SQL Fiddle for it:
http://sqlfiddle.com/#!12/c4c96/2/0
-
1There have to be two or more rows with the same values. As it stands, your query will return every row (since a row will always match itself). See the questioner's own answer.2013年08月04日 15:28:15 +00:00Commented Aug 4, 2013 at 15:28
-
update the fiddle please, it does not works anymoreVictor– Victor2018年05月14日 23:58:20 +00:00Commented May 14, 2018 at 23:58
2 3 4 5
and2 3 4 9
in the results?2
is not equal to3
.