2017-01-14 24 views
3

我有一個顯示項目列表的頁面。與每個項目被顯示從mysqli的數據庫中檢索到的以下數據:SELECT,SELECT COUNT和交叉引用表只能由一個查詢處理嗎?

  1. 標題
  2. 字幕
  3. 說明
  4. 零件數目(×1)
  5. 的與該相關聯的照片總數項目
  6. 從項目中隨機選擇的照片
  7. 標籤列表

項目使用的是分頁系統

由於這是基於我的一個老項目顯示每頁6個,它最初是草率的代碼完成(我也是剛學,不知道任何更好)使用許多查詢。實際上,其中的三項僅用於5-7項,並且這些項目都包含在與分頁系統一起工作的while循環中。我現在很清楚,這甚至不是做生意的正確方法。

我所熟悉的INNER JOIN和使用子查詢,但我很擔心,我未必能得到所有僅使用一個基於以下原因選擇查詢這些數據:

  • 項目1-4是一個基本的SELECT查詢很容易,但是...

  • 第5項需要SELECT COUNT AND ...

  • 項目6需要一個基本SELECT查詢與ORDER by RAND LIMIT 1到 選擇一個隨機照片出所有與每個項目 相關的那些(使用FilesystemIterator是不可能的,因爲照片 表具有指示0,如果相片是不活動的和1如果它是 活性列)

  • 第7項是由交叉引用表選擇

鑑於標籤和 項目,包含標籤標識和名稱的表,我不能肯定,如果這一切都可以(R偶數應就此而言)只需要一個查詢就可以完成,或者如果它需要m而不是一個查詢。我已經反覆閱讀了如何用報紙在鼻子上劃一個或多個查詢來在一個while循環中嵌套。我甚至讀過多個查詢,一般來說,這是一個壞主意。

所以我卡住了。我意識到這可能聽起來太籠統了,但我沒有任何可行的代碼,只是使用4個查詢來完成這項工作的舊代碼,其中3個嵌套在while循環中。

數據庫結構如下。

項目表:

+-------------+---------+----------+---------------+------+ 
| project_id | title | subtitle | description | part | 
|---------------------------------------------------------| 
|  1  | Chevy | Engine | Modify  | 1 | 
|  2  | Ford | Trans | Rebuild  | 1 | 
|  3  | Mopar | Diff  | Swap   | 1 | 
+-------------+---------+----------+---------------+------+ 

照片表:

+----------+------------+--------+ 
| photo_id | project_id | active | 
|--------------------------------| 
|  1 |  1  | 1 | 
|  2 |  1  | 1 | 
|  3 |  1  | 1 | 
|  4 |  2  | 1 | 
|  5 |  2  | 1 | 
|  6 |  2  | 1 | 
|  7 |  3  | 1 | 
|  8 |  3  | 1 | 
|  9 |  3  | 1 | 
+----------+------------+--------+ 

標籤表:

+--------+------------------+ 
| tag_id |  tag  | 
|---------------------------| 
| 1 | classic   | 
| 2 | new car   | 
| 3 | truck   | 
| 4 | performance  | 
| 5 | easy    | 
| 6 | difficult  | 
| 7 | hard    | 
| 8 | oem    | 
| 9 | aftermarket  | 
+--------+------------------+ 

標籤/項目交叉引用表:

+------------+-----------+ 
| project_id | tag_id | 
|------------------------| 
|  1  |  1  | 
|  1  |  3  | 
|  1  |  4  | 
|  2  |  2  | 
|  2  |  5  | 
|  3  |  6  | 
|  3  |  9  | 
+------------+-----------+ 

我並不是要求爲我寫代碼,但如果我問的是有道理的話,我會誠懇地感謝一個正確的方向。很多時候,我在網上苦於PHP和MySQLi手冊,所以如果有什麼辦法可以打破這種情況,那就太好了。

非常感謝大家。

+0

我認爲這可以用一個查詢和一個聯合的子查詢來完成。一個查詢可以得到1-5和7。讓我在回答之前先嚐試 – newGuy

回答

3

你可以做你的子查詢子句SELECT裏面,像這樣:

SELECT 
    p.title, p.subtitle, p.description, p.part, 
    (SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos, 
    (SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo 
FROM projects as p 

現在,對於標籤的列表中,因爲它返回多行,你不能做一個子查詢和你應該爲每個項目做一個查詢。那麼,事實上,如果你以某種串聯方式返回所有標籤,就像逗號分隔列表一樣:tag1,tag2,tag3 ...但我不建議你這樣做,因爲你需要分解列值。只有當你有很多項目時,才能做到這一點,並且檢索每個單獨項目的標籤列表的性能相當低。如果你真的想,你可以:

SELECT 
    p.title, p.subtitle, p.description, p.part, 
    (SELECT COUNT(photo_id) FROM Photos where project_id = p.project_id) as total_photos, 
    (SELECT photo_id FROM Photos where project_id = p.project_id ORDER BY RAND LIMIT 1) as random_photo, 
    (SELECT GROUP_CONCAT(tag SEPARATOR ', ') FROM tags WHERE tag_id in (SELECT tag_id FROM tagproject WHERE project_id = p.project_id)) as tags 
FROM projects as p 
+0

Ho-Lee-Cow!我迫不及待地想要試試這個......讓我看看我是否能夠直接得到這個結果......你是指每個項目上面運行整個查詢還是每個項目只運行一個來獲取標籤?現在,分頁代碼一次抽取6個項目(或者我設定的任何項目)。對我來說,交叉引用表就是保留......我是否正確地理解你? – mileaminute

+0

yup,that works – newGuy

+0

@mileaminute如果你運行第二個查詢,它將是一個單一的查詢滿足你的所有需求,但「標籤」列將需要爆炸(http://php.net/manual/en/ function.explode.php)以逗號獲得每個標籤的數組 –

1

正如你從項目1到4所說,你已經有了解決方案。

添加到相同的查詢SQL_CALC_FOUND_ROWS代替SELECT COUNT解決項目5

對於第6項,你可以使用一個subquery或者一個LEFT JOIN限制到一個結果。

有關最新的項目,您還可以使用子查詢加盟一個結果所有的標籤(用逗號例如分隔)。