First of all, I don't think my title is good, but I couldn't think of a better one. Please feel free to change it.
I have a table that keeps record of a pair of rows.
The following is a 开发者_运维知识库sample table structure.
table History
user_id row_1 row_2
2 1 2
2 1 3
table Rows
row_id
1
2
3
4
5
6
I would like to query to get only a pair of rows that are not in the 'History' table.
so..I like to get the following result.
row pairs:
1,4
1,5
1,6
2,3
2,4
2,5
2,6
and so on
Can I do it with one query?
Just added:
I just made a query that works, but I am not sure about the performance.
select r1.row_id, r2.row_id from rows as r1 cross join rows as r2
where r1.row_id!=r2.row_id and ( r1.row_id + r2.row_id) not in (select row_1 + row_2 from history)
order by r1.row_id desc
Would it be super slow?
Something like this. You haven't made the correlations clear between the fields but this should be easy to adapt.
select h.row_id r1, r.row_id r2
from rows h
cross join rows r
left join history h2 on h2.row_1=h.row_id and h2.row_2=r.row_id
where h2.row_1 is null
The CROSS JOIN produces all the possible combinations of row_id x row_id
THE LEFT JOIN attempts to find the combination in the history table
The WHERE clause picks out where the combination is not found
I think this might work:
SELECT DISTINCT
CASE WHEN r1.row_id < r2.row_id THEN r1.row_id ELSE r2.row_id END AS row_id_1,
CASE WHEN r1.row_id < r2.row_id THEN r2.row_id ELSE r1.row_id END AS row_id_2
FROM Rows AS r1
INNER JOIN Rows AS r2 /* ON r1.row_id <> r2.row_id */
WHERE (r1.row_id, r2.row_id) NOT IN (
SELECT row_1, row_2
FROM history
UNION
SELECT row_2, row_1
FROM history
)
ORDER BY 1, 2
Returns:
1, 1
1, 4
1, 5
1, 6
2, 2
2, 3
2, 4
2, 5
2, 6
3, 3
3, 4
3, 5
3, 6
4, 4
4, 5
4, 6
5, 5
5, 6
6, 6
This query will be super slow.
精彩评论