0

私は小さなデータベースを持っており、400頭弱のポニーの詳細を保持しています。そのテーブルをクエリして、各ポニーの関連する詳細と、その所有者とブリーダーの名前を示すテーブルを返したいと思います。データは主に次のように保持されます。

  1. プロファイル-個々のポニーに割り当てられたすべての情報を保持するテーブル。これには、父と母の登録番号、所有者とブリーダーのDBに割り当てられたIDが含まれます。
  2. 連絡先-人々の情報のためのテーブル。以下のクエリで「所有者」として、また「ブリーダー」として参加しました。
  3. prm_ *-色、品種などの幅広い詳細を保持する複数のパラメータテーブル。

私が問題に直面しているのは、最初の自己結合を試みたときです。各プロファイルの父と母の名前、および最初にポニー自身の名前を取得するために、プロファイルテーブルを3回クエリします。クエリを実行すると、多くの(すべてではない)プロファイルに対して重複する行が返されます。DISTINCTを使用すると、これらのほとんどが排除されましたが、特に種雄牛やダムが記録されていないポニーの場合、結果が同じではないという問題が残ります。

私は問題をグーグルで検索しました、そしてそれはあちこちに現れます、しかし私は与えられた解決策で何が起こっているのかを完全に理解することができません。なぜ問題が発生するのか、まったくわかりません。誰かが私に問題とその解決をステップスルーしてくれませんか?私は最も感謝するでしょう。

現状の私のクエリ(わずか387匹のポニーから408の結果を返します!):

include 'conn.php';
        ?>
<table class="admin-display">
<thead><tr><th>No:</th><th>Name:</th><th>Sire:</th><th>Dam:</th><th>Age:</th><th>Colour:</th><th>Gender:</th><th>Owner:</th><th>Breeder:</th></tr></thead>  
<?php
$i=1;

$sql = mysql_query("SELECT DISTINCT p.ProfileID, p.ProfileOwnerID, p.ProfileBreederID, p.ProfilePrefix, p.ProfileSireReg, p.ProfileDamReg,
                p.ProfileGenderID, p.ProfileAdultColourID, p.ProfileColourModifierID, p.ProfileYearOfBirth, 
                p.ProfileYearOfDeath, p.ProfileLocalRegNumber, p.ProfileName,
                sire.ProfileName AS sireName, sire.ProfilePrefix AS sirePrefix,
                dam.ProfileName AS damName, dam.ProfilePrefix AS damPrefix,
                owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
                breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
                BreedGender, BreedColour, BreedColourModifier
                FROM profiles AS p
                    LEFT JOIN profiles AS sire
                        ON p.ProfileSireReg = sire.ProfileLocalRegNumber
                    LEFT JOIN profiles AS dam
                        ON p.ProfileDamReg = dam.ProfileLocalRegNumber
                            LEFT JOIN contacts AS owner
                                ON p.ProfileOwnerID = owner.ContactID
                            LEFT JOIN contacts AS breeder
                                ON p.ProfileBreederID = breeder.ContactID
                    LEFT JOIN prm_breedgender
                                ON p.ProfileGenderID = prm_breedgender.BreedGenderID
                            LEFT JOIN prm_breedcolour
                                ON p.ProfileAdultColourID = prm_breedcolour.BreedColourID
                            LEFT JOIN prm_breedcolourmodifier
                                ON p.ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
                          WHERE p.ProfileName != 'Unknown'
                          ORDER BY p.ProfileID ASC");

while($row = mysql_fetch_array($sql)) {

    $id = $row['ProfileID'];
    $name = $row['ProfilePrefix'] . ' ' . $row['ProfileName'];
    if ($row['ProfileYearOfDeath'] > 0000) { $age = ($row['ProfileYearOfDeath'] - $row['ProfileYearOfBirth']); }
    elseif ($row['ProfileYearOfDeath'] <= 0000) { $age = (date('Y') - $row['ProfileYearOfBirth']); }
    $reg = $row['ProfileLocalRegNumber'];
    $sire = $row['sirePrefix'] . ' ' . $row['sireName'];
    $dam = $row['damPrefix'] . ' ' . $row['damName'];
    $colour = $row['BreedColour'];
    $gender = $row['BreedGender'];
    $owner = $row['owner_fname'] . ' ' . $row['owner_lname'];
    $breeder = $row['breeder_fname'] . ' ' . $row['breeder_lname'];

    echo '<tr><td>' . $i++ . '</td><td>' . $name . '</td><td>' . $sire . '</td>';
    echo '<td>' . $dam . '</td><td>' . $age . '</td><td>' . $colour . '</td><td>' . $gender. '</td>';
    echo '<td>' . $owner . '</td><td>' . $breeder. '</td></tr>';
}
echo '</table>';

mysql_close($con);
4

2 に答える 2

0

問題はデータにあります-結合しているテーブルの1つに、結合キーに関連付けられた複数の行があります。

クエリを段階的に実行することをお勧めします。基本クエリから開始します(フィールドリストを取り出します)。

SELECT count(*)
    FROM profiles AS p
    WHERE p.ProfileName != 'Unknown'

次に、カウントの増加が表示されるまで、結合テーブルを一度に1つずつ追加します...

SELECT count(*) 
    FROM profiles AS p
    LEFT JOIN profiles AS sire
        ON p.ProfileSireReg = sire.ProfileLocalRegNumber
    WHERE p.ProfileName != 'Unknown'

これで、重複がどこにあるかを確認できるはずです。重複しているレコードを簡単に確認したい場合は、次のクエリを実行できます。

SELECT p.Profile_id, count(*) cnt
    FROM profiles AS p
    LEFT JOIN profiles AS sire
        ON p.ProfileSireReg = sire.ProfileLocalRegNumber
    -- (all other joins)
    WHERE p.ProfileName != 'Unknown'
    GROUP BY p.Profile_id
    HAVING count(*) > 1

次に、複製されたレコードの詳細を確認できます。

于 2011-08-19T16:03:10.157 に答える
0

使用GROUP BYするDISTINCT

http://msmvps.com/blogs/robfarley/archive/2007/03/24/group-by-v-distinct-group-by-wins.aspx

于 2011-08-19T16:19:28.637 に答える