假设我有两列:
_______________
| id1 | id2 |
|------|------|
| 1 | 2 |
| 2 | 1 |
| 3 | 4 |
| 4 | 1 |
| 4 | 3 |
| 1 | 4 |
...
如果我有一行id1 = 1且id2 = 2,那么在它之后会有一行,即id1 = 2和id2 = 1.
如何获得每个(id1,id2)对的顶部?
更新
示例的结果应为:
row1: 1 | 2
row2: 3 | 4
row3: 4 | 1
答案 0 :(得分:2)
链接回原始表很大程度上取决于该表中导致订单的内容。让我们说你有一个日期字段或一个序列字段,你想要最小的值......
在这个例子中,我假设seqField按行
是唯一的然后它看起来像这样:
--drop table #test
SELECT 1 as seqField, 1 as id1, 2 as id2
INTO #test
UNION ALL
SELECT 2,2,1
UNION ALL
SELECT 3,3,4
UNION ALL
SELECT 4,4,1
UNION ALL
SELECT 5,4,3
UNION ALL
SELECT 6,1,4
UNION ALL
SELECT 7,10,20;
WITH norm AS
(
SELECT CASE WHEN id1 > id2 THEN id1 ELSE id2 END as a,
CASE WHEN id1 < id2 THEN id1 ELSE id2 END as b, *
FROM #test
), setList AS
(
SELECT DISTINCT a, b, min(seqField) as s
FROM norm
GROUP BY a, b
)
SELECT #test.*
FROM #test
JOIN setList ON #test.seqField = setList.s
这给出了
seq id1 id2
1 1 2
3 3 4
4 4 1
7 10 20
正如sqlchan指出的那样,如果您没有要使用的现有列,则可以用%%physloc%%
替换seqField。
答案 1 :(得分:0)
您可以使用联接来查找与id1, id2
倒置的匹配对:
select t2.*
from YourTable t1
join YourTable t2
on t2.id1 = t1.id2
and t2.id2 = t1.id1
答案 2 :(得分:0)
我很确定你可以做到:
SELECT `id1`, `id2`
FROM `table`
GROUP BY `id1`, `id2`
ORDER BY `id1`, `id2`
好的,从(1,2)和(2,1)显示出来:
SELECT `id1`, `id2`
FROM `table` a
WHERE NOT EXISTS (
SELECT TOP 1 1
FROM `table` b
WHERE b.`id1` < b.`id2` AND b.`id1` = a.`id2` AND b.`id2` = a.`id1'
)
ORDER BY `id1`, `id2`
如果您想实际保留订单以便显示第一行,那么您需要使用ROWID
(更多信息:http://www.sqlite.org/autoinc.html)
SELECT id1, id2
FROM `table` a
WHERE NOT EXISTS (
SELECT TOP 1 1
FROM `table` b
WHERE b.ROWID < a.ROWID AND b.id1 = a.id2 AND b.id2 = a.id1
)
结果:
row1: 1 | 2
row2: 3 | 4
row3: 4 | 1
答案 3 :(得分:0)
在id1 + "|" + id2
上采用不同的方式。例如这只是概念,我现在还没有尝试过,SELECT DISTINCT(CONCAT(id1,'|',id2)) FROM ...
。 Seph对group by的推荐会更有意义
答案 4 :(得分:0)
在SQL Server 2008中......
SELECT a.col1,a.col2
FROM answer a
JOIN answer b ON a.col1 = b.col2 and b.col1 = a.col2
and a.%%physloc%% = (SELECT MIN(c.%%physloc%%)
FROM answer c WHERE c.col1 = a.col1 and c.col2 = a.col2)
and b.%%physloc%% = (SELECT MIN(c.%%physloc%%)
FROM answer c WHERE c.col1 = b.col1 and c.col2 = b.col2)
ORDER BY CASE
WHEN a.col1 > a.col2
THEN a.col2
ELSE b.col2
END
但是我不会使用%% physloc %%(太internalesque) - 如果顺序很重要,我会引入一个rowid标识列。 对于Oracle,您可以使用ROWID,而不必担心添加列。