私は比較的複雑なクエリである(私の限られMYSQLの知識を持つ)ものを持っている:このクエリに多対多のテーブルのリレーションシップを追加する
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS
songsID, song_name, artist_band_name, author, song_artwork, song_file,
song_description, uploaded_time, emotion, tempo,
user, happiness, instruments, similar_artists, play_count,
projects_count,
rating, ratings_count, waveform, datasize, display_name, user_url,
IF(user_ratings_count, 'User Voted', 'Not Voted') as voted
FROM (
SELECT
sp.songsID, projects_count,
AVG(rating) as rating,
COUNT(rating) AS ratings_count,
COUNT(IF(userid=$userid, 1, NULL)) as user_ratings_count
FROM (
SELECT songsID, COUNT(*) as projects_count
FROM $sTable s
LEFT JOIN $sTable2 p ON s.songsID = p.songs_id
GROUP BY songsID) as sp
LEFT JOIN $sTable3 r ON sp.songsID = r.songid
GROUP BY sp.songsID) as spr
JOIN $sTable s USING (songsID)
LEFT JOIN $sTable5 q ON s.user = q.ID
$sWhere
$sOrder
$sLimit
このクエリは、5から与えられた曲に関するすべての情報を取得します異なるテーブル。
変数$ sWhereはクエリのWHERE部分を作成し、ユーザーの入力に基づいてこの曲のリストを動的にフィルタ可能にするためにサーバーに送信されるデータに依存します。
$ sOrderと$ sLimitを注文し、ユーザーの入力に基づいて結果を再度制限します。
ジャンルのリスト(wp_genres)を含むこの式に6番目のテーブルを追加する必要があります。このテーブルは$ sTableのsongsIDカラムにリンクテーブル(wp_song_genres)を介して次の構造でリンクされています。
$sTable(wp_songs) $sTable6(wp_genre_songs) $sTable7(wp_genres)
songsID* song_id* genre_id**
column2 genre_id** genre_name
column3 icon_url
column4
column5
etc...
アスタリスクはリンクを表します。
私がする必要があるのは、曲の結果の動的フィルタがジャンル別に曲のリストをフィルタリングできるようにすることですが、新しいテーブルを導入する方法を考えることはできません($ sTable6と$ sTable7)をクエリに追加します。
この部分は「SSEARCH」を介して受け取ったテキストを取り、任意の一致するテキストの列を検索します。
以下は私のクエリのWHEREの部分を生成するコードです。ユーザが入力最小テンポ値と(フォント端にjqueryの範囲スライダを介して行われる)最大テンポ値できるよう
$sWhere = "";
if ($_GET['sSearch'] != "")
{
$aWords = preg_split('/\s+/', $_GET['sSearch']);
$sWhere = "WHERE (";
for ($j=0 ; $j<count($aWords) ; $j++)
{
if ($aWords[$j] != "")
{
$sWhere .= "(";
for ($i=0 ; $i<count($aColumns) ; $i++)
{
$sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string($aWords[$j])."%' OR ";
}
$sWhere = substr_replace($sWhere, "", -3);
$sWhere .= ") AND ";
}
}
$sWhere = substr_replace($sWhere, "", -4);
$sWhere .= ')';
}
この部分は、「範囲」フィルタです。データはsSearch_ *を介して受信されます。
/* Individual column filtering */
for ($i=0 ; $i<count($aColumns) ; $i++)
{
if ($_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '')
{
if ($sWhere == "")
{
$sWhere = "WHERE ";
}
else
{
$sWhere .= " AND ";
}
$columnFilterValue = mysql_real_escape_string($_GET['sSearch_' . $i]);
// check for values range
$rangeSeparator = "~";
if (!empty($rangeSeparator) && strstr($columnFilterValue, $rangeSeparator)) {
// get min and max
$columnFilterRangeMatches = explode('~', $columnFilterValue);
// get filter
if (empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1]))
$sWhere .= " 0 = 0 ";
else if (!empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1]))
$sWhere .= $aColumns[$i] . " BETWEEN '" . $columnFilterRangeMatches[0] . "' and '" . $columnFilterRangeMatches[1] . "' ";
else if (empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1]))
$sWhere .= $aColumns[$i] . " < '" . $columnFilterRangeMatches[1] . "' ";
else if (!empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1]))
$sWhere .= $aColumns[$i] . " > '" . $columnFilterRangeMatches[0] . "' ";
} else {
$sWhere .= $aColumns[$i] . " LIKE '%" . $columnFilterValue . "%' ";
}
}
}
genre_idのデータはsSearch_23経由で入力されます。つまり、$ _GET ['SSearch ']に結果をフィルタリングするgenre_idが含まれます。多くのジャンルタグの結果を一緒に追加する必要があることに注意してください。
ユーザーがジャンルを選択した場合:rock(genre_id:1)$ sTableのgenre_id:1が関連付けられているすべての曲が返されます。 (現在のクエリで検索された曲に関する残りの情報と一緒に)
しかし、ユーザーがジャンルを選択した場合:rock(genre_id:1)ANDジャンル:pop(genre_id:2)AND genenre:rap
私はこのような複雑な質問であり、私はそれをうまく表現していない可能性があることを私は謝ります。私の現在のコードに関係なく、私は本当に誰かが私を助けることができるか、または私に正しい方向に少なくともpintを願っています。
多くのありがとう!
編集:私はちょうど私のクエリにfollingを追加することによって、「ほとんどの仕事に彼を得るためにanagedいる
:
LEFT JOIN (
SELECT igs.song_id, igs.genre_id, g.genre_name
FROM $sTable6 AS igs
JOIN wp_genres AS g
ON igs.genre_id = g.genre_id
) as gs
ON songsID = gs.song_id
だから、全体のことは今見えることのように: -
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS
songsID, song_name, artist_band_name, author, song_artwork, song_file,
genre, song_description, uploaded_time, emotion, tempo,
user, happiness, instruments, similar_artists, play_count,
projects_count,
rating, ratings_count, waveform, datasize, display_name, user_url, genre_id,
IF(user_ratings_count, 'User Voted', 'Not Voted') as voted
FROM (
SELECT
sp.songsID, projects_count,
AVG(rating) as rating,
COUNT(rating) AS ratings_count,
COUNT(IF(userid=$userid, 1, NULL)) as user_ratings_count
FROM (
SELECT songsID, COUNT(*) as projects_count
FROM $sTable s
LEFT JOIN $sTable2 p ON s.songsID = p.songs_id
GROUP BY songsID) as sp
LEFT JOIN $sTable3 r ON sp.songsID = r.songid
GROUP BY sp.songsID) as spr
LEFT JOIN (
SELECT igs.song_id, igs.genre_id, g.genre_name
FROM $sTable6 AS igs
JOIN wp_genres AS g
ON igs.genre_id = g.genre_id
) as gs
ON songsID = gs.song_id
JOIN $sTable s USING (songsID)
LEFT JOIN $sTable5 q ON s.user = q.ID
$sWhere
$sOrder
$sLimit
genre_idによるクエリは、現在、完全に動的に行われます。しかし、クエリのWHERE部分にgenre_idが指定されていない場合、私は行を二重にしています。曲/ジャンルのリンクテーブルにエントリを持つ各曲が複製されます。
まず、私の現在の解決策は、最適化/ベストプラクティスという点で優れた解決策ですか?次に、これらの重複行をどのようにして防ぐことができますか?
注:リンクテーブルの両方の列に一意のプライマリキーが既にあります。
幻想的な読書のように見えます。私はあなたにそれを投稿する時間を割いてくれて非常に感謝しています。これは非常に便利です。それは私の質問に答えるのではなく、非常に感謝しています。乾杯! :-) – gordyr