我正在尝试基于两列对表进行SQL选择,但不是通常的方式,两列中的值组合必须是唯一的;我想选择值只能在任一列中出现一次的位置。 鉴于数据集:
|pkid | fkself | otherData |
|-----+--------+-----------|
| 1 | 4 | there |
| 4 | 1 | will |
| 3 | 6 | be |
| 2 | 5 | other |
| 5 | 2 | data |
| 6 | 3 | columns |
我需要返回
|pkid | fkself | otherData |
|-----+--------+-----------|
| 1 | 4 | there |
| 3 | 6 | be |
| 2 | 5 | other |
或
|pkid | fkself | otherData |
|-----+--------+-----------|
| 4 | 1 | will |
| 5 | 2 | data |
| 6 | 3 | columns |
我能想到的唯一方法是按顺序连接`pkid
和fkid
,以便第1行和第2行都连接到1,4
,但我是不知道怎么做,或者甚至可能。
行将包含其他数据列,但是我得到的行无关紧要,只是我只获取每个ID一次,无论该值是pkid
还是fkself
。
答案 0 :(得分:1)
您可以使用least
和greatest
来获取两者中最小或最大的值。这允许您按正确的顺序将它们生成为您生成这些键。您可以按照建议连接值,但在此解决方案中不需要它。使用dense_rank,您可以为每个虚构键生成序列。然后,您可以从该序列中获取第一个OtherData。
select
pkid,
fkself,
otherData
from
(select
pkid,
fkself,
otherData,
dense_rank() over (partition by least(pkid, fkself), greatest(pkid, fkself) order by pkid) as rank
from
YourTable t)
where
rank = 1
答案 1 :(得分:0)
你的想法是可能的,它应该产生你想要的结果。
SELECT DISTINCT joinedID
FROM (
SELECT min(id) & "," & max(id) as joinedID
FROM (
SELECT pkid as id, someUniqueValue
FROM table
UNION ALL
SELECT fkself as id, someUniqueValue
FROM table)
GROUP BY someUniqueValue )
这将为您提供唯一的ID列表,您可以根据需要进行连接。您可以通过将其添加到每个SELECT
语句中来轻松包含其他字段。此外,someUniqueValue
可以是现有的唯一字段,新的唯一字段,也可以是连接的pkid
和fkself
,如果该组合是唯一的。
答案 2 :(得分:0)
我能想到的唯一方法是连接`pkid和 fkid按顺序排列,以便第1行和第2行都连接到1,4, 但我不知道该怎么做,或者甚至可能。
您可以使用Oracle中的CASE语句来执行此操作:
SQL> SELECT * FROM sample
2 /
PKID FKSELF
---------- ----------
1 4
4 1
3 6
2 5
5 2
7 7
6 rows selected.
SQL> l
1 SELECT DISTINCT *
2 FROM (
3 SELECT CASE WHEN pkid <= fkself THEN pkid||','||fkself
4 ELSE fkself||','||pkid
5 END "JOINED"
6 FROM sample
7* )
SQL> /
JOINED
-------------------------------------------------------------------------------
1,4
2,5
3,6
7,7