sql >> データベース >  >> RDS >> Sqlserver

ビューから重複行を削除するにはどうすればよいですか?

    行に異なる列がある場合、 DISTINCT は役に立ちません。明らかに、結合しようとしているテーブルの 1 つに、別のテーブルの 1 つの行に対して複数の行があります。 1 つの行を戻すには、結合しているテーブル内の他の複数の行を削除する必要があります。

    これを行う最も簡単な方法は、where 句または JOIN 制限を強化して、必要な単一のレコードにのみ結合することです。通常、これには、他のテーブルから常に「正しい」エントリを選択するルールを決定する必要があります。

    次のような単純な問題があるとします:

    Person:  Jane
    Pets: Cat, Dog
    

    ここで単純な結合を作成すると、Jane の 2 つのレコードを受け取ります:

    Jane|Cat
    Jane|Dog
    

    あなたの視点が人とペットのすべての組み合わせをリストすることである場合、これは完全に正しいです。しかし、あなたのビューが代わりにペットを飼っている人をリストしたり、人をリストしてペットの 1 人を表示したりすることになっていたら、今抱えている問題にぶつかります。このためには、ルールが必要です。

    SELECT Person.Name, Pets.Name
    FROM Person
      LEFT JOIN Pets pets1 ON pets1.PersonID = Person.ID
    WHERE 0 = (SELECT COUNT(pets2.ID) 
                 FROM Pets pets2
                 WHERE pets2.PersonID = pets1.PersonID
                    AND pets2.ID < pets1.ID);
    

    これが行うことは、結合の Pets レコードを最小 ID (Pets テーブルの最初) を持つ Pet に制限するルールを適用することです。 WHERE 句は基本的に、「同じ人物に属し、より低い ID 値を持つペットが存在しない場所」を示しています。

    これにより、1 レコードの結果が得られます:

    Jane|Cat
    

    ビューに適用する必要があるルールは、使用している列のデータと、「複数の」レコードのどれを列に表示するかによって異なります。ただし、それは一部のデータを非表示にすることになり、これは望ましくない場合があります。たとえば、上記のルールは、ジェーンが犬を飼っているという事実を隠します。 Jane には猫しかいないように見えますが、これは正しくありません。

    有効なデータを除外し始めている場合は、ビューの内容とビューで何を達成しようとしているのかを再考する必要があるかもしれません。



    1. mysqlユニオンタイプクエリをカウントします

    2. SQL-BIGINTをINTに安全にダウンキャストします

    3. PostgreSQLは配列要素に一意性の制約を設けることができますか?

    4. SQL算術演算子