2011-09-10 13 views
1

私のデータベースからいくつかのデータを返すには、次のmysqlクエリを使用しています。現在のところ、citiesテーブルには何も入っていません。このクエリは、見つかった最初に一致するエントリだけを返し、一致するエントリはすべて見つからないことに気付きました。すべてのテーブルから一致するすべての結果を返すようにこのクエリを変更する方法はありますか?mysqlクエリの組み込みに問題があります

私が$ query = 'h'に行った場合、クエリはhで始まるすべてのイベント、会場、都市を返すはずです。

SELECT name, 'Events' as source 
FROM events 
WHERE name LIKE '".$query."%' 
UNION ALL  
SELECT name, 'Venues' as source 
FROM venues 
WHERE name LIKE '".$query."%' 
UNION ALL 
SELECT name, 'Cities' as source 
FROM cities 
WHERE name LIKE '".$query."%' 
OR FIND_IN_SET('".$query."%', Alternate_name) 

解決策を投稿するのではなく、修正する方法を説明してください。私はまだ学んでおり、理解したい。

編集:(文字Hを含む$クエリー変数で)置換後

クエリ:次のように

SELECT name, id, 'Events' as source FROM events_basic WHERE name LIKE 'h%' UNION ALL 
SELECT name, fsq_id, 'Venues' as source FROM venues_cache WHERE name LIKE 'h%' UNION ALL 
SELECT name, geo_id, 'Cities' as source FROM static_cities WHERE name LIKE 'h%' OR FIND_IN_SET('h%', alternate_names) 

私が使用したPHPのコードは次のとおりです。 `

$query = 'h'; 

$query = $this->db->query("SELECT name, 'Events' as source FROM events WHERE name LIKE ".$query."%' UNION ALL 
SELECT name, 'Venues' as source FROM venues WHERE name LIKE '".$query."%' UNION ALL 
SELECT name, 'Cities' as source FROM cities WHERE name LIKE '".$query."%' OR IND_IN_SET('".$query."%', Alternate_name)"); 
    if($query->num_rows > 0) 
    { 
     $results = $query->row_array(); 
     print_r($results); 
    }` 

考えられるのは、変数$ queryには、イベント、都市または会場の名前または部分名が格納されているということです。クエリは、指定された名前と一致するイベント、会場、都市の名前を返します。私は十分に明確化されたiveを望む、そうでなければ、もっと明確にしようとするだろう。

+1

あなたのSQLは正しいようです。あなたはFIND_IN_SET条件については説明しませんが、ORとなっているので、何の問題も起こっていないと推測しています。問題の正確さを説明するためにいくつかのデータサンプルを与えることで、さらに説明できますか? – wisefish

+0

このSQLクエリとフェッチステートメントも実行するPHPコードを投稿してください。 – Astha

+0

上記の私の質問をPHPコードで編集しました。 – Derek

答えて

0

の後にSQLクエリを投稿してください。 2番目の一重引用符の位置の違いに注意してください。たとえば、WHERE name LIKE 'h%'ではなく、フレーズ(たとえば、WHERE name LIKE 'h'%)を生成して、連結の間違った場所に2番目の一重引用符を配置しているようです。 。

名前がH(ちょうどH)の都市がある場合や、名前のリストに「H」だけ表示されている場合は、このような状況が発生します。本当?あなたが説明を求めたので、

また、:

  • を単一コンマ別のフィールドに別の都市名を配置するあなたの技術では、データベースの正規化の原則に違反します。 「適切な」構造は、「名前」と「代替」という2つの列を持つ新しいテーブルを作成することです。代替名を持つ都市では、代替名ごとに代替テーブルに1つのエントリがあります。とりわけ、現在のバージョンでは都市検索では不可能なインデックスを使用するために、代替名に対する検索が可能になります。

  • 変数$ queryの内容を「サニタイズ」して、誰かがあなたのサイトでSQLインジェクション攻撃を開始していないことを確認する必要があります(実際のSQLコマンドをクエリフィールド)。さらに良いことに、lookとandを使用して、サーバーがこの代用を実行するようなパラメーター化された照会を使用します。

+0

確かに、置換後のクエリは以下の通りです: 興味深いことに、私は代替名がdb正規化に違反しているのか分かりませんでした。私はgeonames.orgプロジェクトから都市の表を得ました。それには、1つの列にすべての代替名を持つ列が付属していました。 入力に入力する前に入力をサニタイズします。現時点では、変数を手動で入力してクエリをテストし、正しい結果が得られることを確認しています。 – Derek

+0

置換されたクエリが正しいと思われます。 static_citiesテーブルに対して1つのSELECTだけを実行するとどうなりますか? 1行、またはいくつか?そして返されると予想される行のデータを投稿することはできますか? –

+0

私のエラーが見つかりました。クエリはうまくいきますが、何らかの理由で、$ query-> row_array();と書いて、結果セット全体を返す '$ query-> result_array();"ではなく最初の行のみを返します。しかし別の質問 - 私は結果セット全体をループするのではなく、Venuesテーブルのみから結果の数を判断する方法はありますか? – Derek

0

WHERE句でFIND_IN_SETが期待する結果は何ですか?あなたが提供した情報から、これを省略できるはずです。あなたがテーブルから別の都市名を一致させるために探しているなら

、このことを考慮してください。

WHERE name LIKE '".$query."%' OR alternate_name LIKE '".$query."%'; 

、あなたの入力をサニタイズしていることを確認してください。誰かが$ query = '1; DROP TABLE会場;

+0

FIND_IN_SETは、MySQLのドキュメントに記載されています。 –

関連する問題