0

私のテーブルには、別のレコードと一致するレコードがいくつかあります。

644432 738987
738987 644432
..
854313 871860
854313 874411
871860 854313
871860 874411
874411 854313
874411 871860

たとえば、と644432一致し、738987738987一致し644432ます(明らかに)。私にとって、それらは同じでなければならず、私は1つだけ(644432または738987)を取得する必要があります。

別の例854313871860と一致し874411ます(それが私がそれらのために6つのレコードを持っている理由です)。

最終的に2つのレコードのみを取得する必要がありますが、どうすればよいですか?

私の英語で申し訳ありませんが、私の質問が明確でない場合は教えてくれてありがとう。

この例では、次のようにテーブルにデータを入力するコードがあります。

DECLARE @DataTable TABLE (ColA  INT, ColB  INT)
insert into @DataTable  values 
(644432,    738987),
(738987,    644432),
(854313,    871860),
(854313,    874411),
(871860,    854313),
(871860,    874411),
(874411,    854313),
(874411,    871860)
select * from @DataTable
4

5 に答える 5

1

これが、ColA と ColB の 2 つの列を持つ DataTable という名前のテーブルであると仮定すると、次のように実行できます。

select distinct Smallest,Largest from
(
  select case when ColA > ColB then ColB else ColA end as Smallest,
  case when ColA > ColB then ColA else colB end as Largest
  from DataTable
) minmax

これは、最小値が常に最初の列にあり、最大値が 2 番目の列にあるように、内部選択を使用して値を再配置します。次に、外側の選択により、個別の値のセットが取り出されます。

于 2013-03-20T11:57:00.443 に答える
0

接続されたセットを見つけるための再帰クエリ。チェーンごとに、番号が最も小さいアイテムが「グループリーダー」として報告されます。

クエリは、最初にペアのメンバーを並べ替えてから、接続されたコンポーネントのチェーンを見つけることで機能します。クラスタに複数の開始点がある場合、この方法は機能しません。(ただし、ループは回避されます)

この構文はPostgresql用であり、Microsoftの場合はRECURSIVEキーワードを省略し、Oracleの場合はを使用する必要がありますCONNECT BY, PRIOR。YMMV。

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE pairs (ONE INTEGER NOT NULL, two INTEGER NOT NULL
        , PRIMARY KEY (one, two)
        );
INSERT INTO pairs(one, two) values
(644432,738987) ,(738987,644432)
,(854313,871860) ,(854313,874411) ,(871860,854313) ,(871860,874411) ,(874411,854313) ,(874411,871860)
        ;

WITH RECURSIVE rope AS (
        WITH opair AS (
                SELECT LEAST(one, two) AS one
                , GREATEST(one, two) AS two
                FROM pairs
                )
        SELECT o.one AS top
        , o.one AS one
        , o.two AS two
        FROM opair o
        WHERE NOT EXISTS ( SELECT * FROM opair x WHERE x.two=o.one)
        UNION ALL
        SELECT k.one AS top
        , p.one AS one
        , p.two AS two
        FROM opair p
        JOIN rope k ON k.two = p.one
        )
SELECT DISTINCT top
        , COUNT(*) AS N_members
FROM rope
GROUP BY top
ORDER BY top
        ;

結果:

CREATE TABLE
INSERT 0 8
  top   | n_members 
--------+-----------
 644432 |         2
 854313 |         8
(2 rows)
于 2013-03-20T13:05:12.373 に答える
0
select n1,n2 from(select a.col1 col1,a.col2 col2,rownum rn from tbl a, tbl b 
where a.col1||a.col2=(b.col2||b.col1)) where mod(rn,2)<>0
union
select a.col1 col1,a.col2 col2 from tbl a left outer join tbl b on 
a.col1||a.col2=(b.col2||b.col1) where b.col1 is null
于 2013-03-20T12:40:26.537 に答える
0

OK、以下の例は 1 レベルの深さのリンクをたどります。もちろん、ストアド プロシージャを使用するか、コードからクエリを作成することで、これを大幅にクリーンアップすることができます。これにより、リンクをたどる追加レベルを簡単に追加できます。

-- Set up an example table
create table DataTable
(
    A int,
    B int
)
GO

insert into DataTable values(644432,738987)
insert into DataTable values(738987,644432)
insert into DataTable values(854313,871860)
insert into DataTable values(854313,874411)
insert into DataTable values(871860,854313)
insert into DataTable values(871860,874411)
insert into DataTable values(874411,854313)
insert into DataTable values(874411,871860)
GO

-- Strip out initial duplicates
select distinct A,B into Pass1
from
(
  select case when A > B then B else A end as A,
  case when A > B then A else B end as B
  from DataTable
) minmax

-- Create a copy that we will update with links between values
select * into Pass2 from Pass1 order by A

update Pass2 set B=x.NewB from
(
  select L.A as OldA,L.B as OldB, R.B as NewB
  from Pass1 L
  inner join Pass1 R on L.B = R.A
) x
where Pass2.A=x.OldA and Pass2.B=x.OldB

update Pass2 set A=x.NewA from
(
  select L.B as OldA, R.B as OldB, L.A as NewA
  from Pass1 L
  inner join Pass1 R on L.B = R.A
) x
where Pass2.A=x.OldA and Pass2.B=x.OldB

-- Dedupe any newly created duplicates
select distinct A,B
from
(
  select case when A > B then B else A end as A,
  case when A > B then A else B end as B
  from Pass2
) minmax
于 2013-03-20T13:48:28.947 に答える
0

これを試して

select col1,col2 from (select col1+col2 as indicator, col1, col2 from table1) インジケータによるグループ

ここでsqlfiddleを参照してください

注 : 2 つの異なる行の合計が同じ場合、これは機能しません。

于 2013-03-20T12:14:16.290 に答える