2011-09-13 5 views
0

2つの列に基づいてテーブルでSQL selectを実行しようとしていますが、通常の方法で両方の列の値の組み合わせが一意でなければなりません。値がどこの列に1回しか表示されないかを選択したい。 は、データセットを考える:列の組み合わせでSQL distinct/groupby

|pkid | fkself | otherData | 
|-----+--------+-----------| 
| 1 | 4 | there | 
| 4 | 1 | will | 
| 3 | 6 |  be | 
| 2 | 5 | other | 
| 5 | 2 | data | 
| 6 | 3 | columns | 

私はこれを行うには、私は考えることができる唯一の方法は、順番に`pkidfkidを連結することである

|pkid | fkself | otherData | 
|-----+--------+-----------| 
| 1 | 4 | there | 
| 3 | 6 |  be | 
| 2 | 5 | other | 

または

|pkid | fkself | otherData | 
|-----+--------+-----------| 
| 4 | 1 | will | 
| 5 | 2 | data | 
| 6 | 3 | columns | 

のいずれかを返す必要がありますその結果、行1と行2の両方が1,4に連結されるようになりましたが、どうすればよいかわかりません。ル。

行には他のデータ列がありますが、値はpkidまたはfkselfのいずれであるかにかかわらず、それぞれのIDは1回だけ取得されます。

答えて

1

leastgreatestを使用して、2つの最小値または最大値を取得できます。これにより、それらのキーを生成する正しい順序でそれらを配置することができます。提案したとおりに値を連結することはできますが、このソリューションでは必要ありません。 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 
+0

を、私は行うことができませんでした: は PKID、 fkself、 を選択 YourTable Tからランク としてOtherDataの、 DENSE_RANK()オーバー(PKIDによってパーティション少なくともによって(PKID、fkself)、最大(PKID、fkself)順)) ランク= 1 それは私に余分な列を与えるが、それは使用すると無視することができます。私は、Oracle DB – AsherMaximum

+0

の中のビューのためにこのステートメントを作成しています。これはうまくいくようです。今度は残りのクエリを追加するだけです! – AsherMaximum

+0

同じレベルのwhere句でランクを使用できないため、副選択が必要です。 – GolezTrol

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は、既存の一意のフィールド、新しい一意のフィールド、または連結されたpkidfkself(その組み合わせが一意の場合)のいずれかになります。

0

これを行うには、私は考えることができる唯一の方法は、行1と行2の両方が1,4に連結なるように順に `PKIDと fkidを連結することである が、私はありませんよそれをどうやって行うのか、それが可能なのかどうかを確かめてください。

あなたは、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 
関連する問題