2011-09-08 11 views
2

Venuesテーブルに会場のリストがあり、Locationsテーブルに市/州のリストがあります。会場は私の組織に固有の市外局番(SOYID)と関連しています。 SOYIDは地理的エリアで構成されています。Locationsテーブルの各行にはCity、State、および対応するSOYIDがあります。 Venuesの行の一部にはSOYIDがあり、それ以外の行にはSOYIDがありません。そうでない人のためには、私は都市と州のためのSOYIDを見つける必要があります。私は特定のSOYIDの中でその会場を選択したいだけです。小さなMySQL結合クエリの最適化

このクエリは機能しますが、読み込むには数秒かかります。私は質問を正しく書いているとは思わない。現在、Venuesには約140行、Locationsには40,000があります。

$sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
      FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city 
      WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
      OR ((c.city = a.City) AND (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "')) 
      ORDER BY a.Name ASC"; 

答えて

2

あなたは左から列を参照する任意の時間はINNER JOINをのように動作するために参加するWHERE句、あなたの力で(あなたの特定のケースでc.statec.SOYID)テーブルに参加しました。代わりに、結合条件のこれらのテストは、一部行います

"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
    FROM Venues AS a 
     LEFT JOIN Locations AS c 
      ON a.City = c.city 
       AND a.StateAbbr = c.state 
       AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
     OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */ 
    ORDER BY a.Name ASC" 

EDIT:私は彼が `をドロップすることができますね

"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr 
    FROM Venues AS a 
    WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "' 
     OR EXISTS(SELECT NULL 
         FROM Locations AS c 
         WHERE a.City = c.city 
          AND a.StateAbbr = c.state 
          AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "') 
    ORDER BY a.Name ASC" 
+0

:コメントに基づいて、このバージョンは、あなたがDISTINCT要件を削除するには許可する必要がありますが今、彼はできない?あるいは、 'DISTINCT'の代わりに' GROUP BY a.VenuID'を使用してください。 –

+0

@ypercube:はい、おそらく 'DISTINCT 'を落とすのは安全だと思います。 –

+0

私は別名をドロップすると、私はまだ繰り返し行を取得するので、私はまだ別名を保持する必要があります。ありがとう! –