我有什麼(用我有限的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個表格,該表格通過具有以下結構的鏈接表(wp_song_genres)鏈接到$ sTable中的songsID列: -
$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)到查詢中。
下面是代碼生成我查詢的WHERE部分:
這部分需要通過「SSEARCH」收到的文本和搜索欄找到任何匹配的文本。
$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 .= ')';
}
這部分是一個「範圍」過濾器,使得用戶能夠輸入的最小速度值和最大速度值(通過一個jquery範圍滑塊完成上的字體端)。數據通過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的所有歌曲。 (約歌曲其餘的信息一起作爲retrievedby
但是...如果用戶選擇流派我當前查詢:巖(genre_id:1)和類型:流行(genre_id:2)和genenre:說唱。 (genre_id:3),那麼所有帶有這些標籤的歌曲都應該被退回。不管我真的希望有人能幫助我,或者至少讓我朝着正確的方向前進
非常感謝!
編輯:
我剛纔anaged通過將folling到我的查詢來獲取他的「近」工作:
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,則會得到dupilcate行。歌曲/流派鏈接表中有條目的每首歌都會被複制。
首先,我的當前解決方案在優化/最佳實踐方面是否合適?其次,我怎樣才能防止這些重複的行?
注意:我已經在鏈接表中的兩列之間有一個唯一的主鍵。
看起來像一個夢幻般的閱讀,我非常感謝您花時間發佈它。這將非常有用。它不回答我的問題,但非常感謝。乾杯! :-) – gordyr