2012-05-10 34 views
-1

的房源我有類似表:特殊的分組和數據庫查詢

ID | NAME | GROUP_ID 
1 | rand_str | 4 
2 | rand_str | 2 
3 | rand_str | 3 
4 | rand_str | 0 
5 | rand_str | 3 
6 | rand_str | 1 
7 | rand_str | 3 
8 | rand_str | 3 
9 | rand_str | 1 
10 | rand_str | 0 

ID是唯一的ID,名稱valie不爲空,包含VARCHAR值和GROUP_ID是最多2位數的正數。

假設查詢返回此表。

我想要的是,使用PHP,顯示按group_id分組的結果,並且如果可能的話,將組編號從最大編號到最小編號排序,並且「0」總是最後一個,不管它是多麼充滿。

因此最終結果:

組ID 3存在3倍,所以

  1. 1- ID_3,ID_5,和ID_7 id_8(GROUP_ID 3)
  2. 2- ID_6,id_9(GROUP_ID 1 )
  3. 3-任一組ID 4或2,因爲兩者都包含1個項目的每個
  4. 4- GROUP_ID 0,即使它有2項 - > ID_4,id_10

我該如何做到這一點?

謝謝。

+0

這將是很容易做的一個SQL查詢比PHP –

+0

@AaronW,我同意。但是,如果沒有PHP,則無法打印查詢結果。 – Phil

回答

4

使用子查詢來確定各組的計數(因此它的順序),然​​後加入用您的數據檢索記錄:

SELECT my_table.* FROM my_table JOIN (
    SELECT GROUP_ID, 
      IF(GROUP_ID = 0, -1, COUNT(*)) AS rank 
    FROM  my_table 
    GROUP BY GROUP_ID 
) AS t USING (GROUP_ID) 
ORDER BY t.rank DESC 

請參閱sqlfiddle

那麼您需要遍歷在PHP中的結果,跟蹤的最後一個記錄的GROUP_ID,並與當前一個比較,看是否在一個新的小組,現在是:

$last = null; 
echo "<table>"; 
while ($row = $stmt->fetch()) { 
    if ($row['GROUP_ID'] !== $last) { 
    if ($last !== null) echo "</tr>"; 
    echo "<tr><th scope='row'>Group " . html_entities($row['GROUP_ID']) . "</th>"; 
    $last = $row['GROUP_ID']; 
    } 
    echo "<td>ID " . html_entities($row['ID']) . "</td>"; 
} 
echo "</tr></table>"; 
+0

我同意你的看法,對我來說似乎是好的方式:)(但是太懶了,不能寫下來) – ykatchou

+0

@eggyal,非常感謝你迴應,但也解釋它。我非常感激。偉大的解決方案,如此優雅我想快速作爲一件事:什麼是IF(GROUP_ID = 0,-1,COUNT(*))的'-1'?這是如何實現使0組最後出現的? – Phil

+0

@Phil:我們定義一個名爲'order'的結果列,它保存每個組中的項目數,除非group_id爲0,在這種情況下,我們將其設置爲-1。然後,當我們按照該列的降序對結果進行排序時,由於-1總是小於任何其他組的結果數量(包括任何不包含任何項目的組),所以group_id 0總是最後顯示。 – eggyal

-1

你可以你需要使用什麼如下因素查詢

select group_concat(id),name, group_id, count(*) entries from grp 
group by group_id 
order by entries desc ; 
+0

這不會將組0排在最後,除非它是唯一擁有最少成員數的組。 – eggyal

+0

@eggyal更新了答案,現在應該可以工作。 –