2011-02-01 4 views
0

私はこのの取得ほとんどの異なる行

C1    C2   C3 
Mike   London  578 
Mike   Bonn   578 
Jane   Madrid  245 
Billy   Paris   345 
Jane   Rome   245 

のようなテーブルがあると私は私を与えるクエリ必要があります。

C1    C2   C3 
Mike   London  578 
Jane   Madrid  245 
Billy   Paris   345 

、私に明確なのようなものを与えるクエリです C1上の同じ値の次の出現を無視します。

編集:これはちょっと簡単なサンプルで、C3が重要だと思う人もいれば、実際のテーブルのように見えるように編集しているようです列、および問題のある行は、値を除いてすべて同一であり、破棄することができます。

+0

私は仕事をすることを期待していましたが、そうではありません。 – Saiyine

+0

私はC1、C2、C3でグループを作成すると、すべてのグループが表示されます。グループをC1、C3で使用すると、C2を表示するときにエラーが発生します。 – Saiyine

+0

"同じ値の次の出現"が何を意味するかを定義する必要があります。 – onedaywhen

答えて

1

あなたはデータがあるレコードから気にしないかのように、あなたはそれを書くことができます:ここでの問題は、分(C2)と分(C3)は、実際のデータを混在させることができることである

SELECT C1, min(C2), min(C3) 
FROM table 
GROUP BY C1 

異なるレコード。あなたは主キーを持っていた場合

、あなたは簡単にIDを避けることができます:セット/関係はデフォルト順不同であるため、実際にSQLで「次の出現」というようなシンプルなコンセプトはありません

SELECT C1, C2, C3 
FROM table t 
WHERE id IN (
    SELECT min(t2.id) 
    FROM table t2 
    GROUP BY t2.C1) 
+0

あまりにも厄介な企業のソフトウェアは、テーブルのレイアウトに依存しているので、私はそれを変更すべきではありません(プライマリキーの欠如について)。 – Saiyine

+0

私はあなたのアプローチがシンプルで、ありがとうございます – Saiyine

+0

あなたはPKを持っているかどうかわかりませんでしたが、最初の解決策で問題を解決するのはまだ簡単です。 –

0

このようなPARITION OVER RANK()(2005、2008)を使用します

declare @table as table (c1 nvarchar(10), c2 nvarchar(10), c3 int, id int identity(1,1)) 

insert into @table values 
('Mike',   'London',  578), 
('Mike',   'Bonn',   234), 
('Jane',   'Madrid',  245), 
('Billy',   'Paris',   345), 
('Jane',   'Rome',   346) 

select c1, c2, c3 from 
(select id, c1, c2, c3, RANK() over (partition by c1 order by id) as Rank from @table) tmp 
where tmp.Rank = 1 
order by id 

使用このような興味深いWHERE句(2000):

select t2.* 
from 
@table t2 
where 
(select COUNT(*) from @table t where t.c1=t2.c1 and (t2.c2 > t.c2 or (t2.c2 = t.c2 and t2.c3 > t.c3))) = 1 
union 
select * from @table where c1 in (select c1 from @table group by c1 having COUNT(*) = 1) 

順序が異なっています上記のように、実際の世界のデータでそれを並べ替える必要があります。

+0

ランクはSQL Server 2005で導入されました:( – Saiyine

+0

、ありがとう、とにかく誰かにとって役に立ちます – Saiyine

+0

2000年版でも更新されました –

1

。 ORDER BY句を使用して行を並べ替える方法を明示的に指定し、必要な行をその順序関係から選択します(SQL Server 2000のTOPを使用)。あなたはC3の降順でソートされているようには見えません(ジェーンは346を持ち、あなたは彼女を245にしたいので)。あなたの言葉に暗黙のうちに暗黙のうちに「次へ」が含まれています(具体的には最初に行が必要です)。このクエリでを最初にと定義する方法を教えてください。あなたは一人一人のC3値を最低にしますか?その場合は、インラインビューでmin(c3)を取得し、そのインラインビューを別のインラインビューに参加させ、別のC1を選択した人でグループ化することができます。

+0

それから、私たちは意志のように感じるC2以外は大丈夫です。 – Saiyine

0

私はおそらく愚かではありますが、distinctはselectのすべての列の明確な組み合わせをとります。

これを達成するには、より多くのデータが必要になります。ここで

は、私はホイップいくつかのコード...このことができます

DECLARE @TBL TABLE(

    ID INT IDENTITY(1,1), 
    C1 VARCHAR(100), 
    C2 VARCHAR(100), 
    C3 INT 

) 
INSERT INTO @TBL VALUES ('Mike','London',578) 
INSERT INTO @TBL VALUES ('Mike','Bonn',234) 
INSERT INTO @TBL VALUES ('Jane','Madrid',245) 
INSERT INTO @TBL VALUES ('Billy','Paris',345) 
INSERT INTO @TBL VALUES ('Jane','Rome',346) 

SELECT * FROM @TBL T 
WHERE 
ID = (SELECT MIN(ID) FROM @TBL CHILD WHERE CHILD.C1 = T.C1) 
GROUP BY ID,C1,C2,C3 

希望ですか?

+0

私はあなたの返信がデモンストレーションの目的であることを認識していますが、私は、ユニークさ以外の何かのためにPKに頼るのを止めるような使命を持っています。それは、山の上の賢者が私の過去の人生で罪のためにexpiateするために私に言ったことです。一意性以外のもの(何らかの一時的な意味に対応させるため)にID(PK)を頼ることは、せいぜいクルーだけです。ロバストなデザインではありません。 OPが最初に入力された行を一時的に(希望していないかもしれません - おそらく最も低いC3値が必要な場合)作成する必要がある場合は、日付作成のdatetime列を使用し、デフォルトのgetdate()を使用します。 – Tim

関連する問題