2012-10-18 16 views
1

我正在建立一個小的內部電話號碼擴展列表。我應該在客戶端代碼中使用多個SQL查詢還是多個循環?

在數據庫中,我有兩個表格,people表格和numbers表格。這種關係分別是one-to-many

我想在單個HTML表格中顯示結果,每行只有一個人,但如果他們有多個數字,它會顯示單行中需要補償的人行上的行數。

現在,從數據庫中獲取的結果一起工作,我既可以做:

(pseudocode) 

SELECT id, name 
FROM people 

foreach result as row { 
    SELECT number 
    FROM numbers 
    WHERE numbers.person_id = row['id'] 
} 

這意味着我做一個查詢來獲取所有用戶,但當時如果我有100用戶,我正在執行100個附加查詢來獲取每個用戶的號碼。

相反,我能做到這一點是這樣的:

(pseudocode) 

SELECT number, person_id 
FROM numbers 

SELECT id, name 
FROM people 

foreach people as person { 
    echo name 
    foreach numbers as number { 
    if (number.id = person.id) { 
     echo number 
    } 
    } 
} 

所以,本質上它是做同樣的事情,除了代替我做兩個查詢來獲取所有通過陣列格式的結果到數組,然後循環我的桌子。

我應該使用哪種方法還是有更好的方法來做到這一點?

回答

4

常見的方法是做一個常規連接:

SELECT id, name, number 
FROM people, numbers 
WHERE people.id = numbers.person_id; 

您可以添加ORDER BY爲了得到這些數字,或者你可以創建一個單一的傳過來的結果集的數組,然後遍歷該數組。

您也可以考慮GROUP_CONCAT來連接所有的號碼爲同一人:

SELECT id, name, GROUP_CONCAT(number SEPARATOR ', ') 
FROM people, numbers 
WHERE people.id = numbers.person_id 
GROUP BY people.id; 

既然你甚至問這個問題:我想強調的是,你應該回暖數據庫設計入門書。它幫助我學習關係數據庫背後的理論。

+0

我相信你的查詢是提問者已經在他的嵌套循環例子中做了什麼,然而,你的'GROUP_CONCAT'這個想法是我可能最終使用的一個很好的想法。 –

+0

morrty在第二個例子中仍然使用兩個查詢。不太好重新加入imo。 –

+0

@EmilVikström對不起。沒有看到頂部的兩個問題,我想他加入了!這加強了我對你的答案的投票哈哈。 –

0

使用存儲過程或函數以檢索數據,不要在程序中,

4

可能要執行只是一個查詢WITE的SQL。類似於

select people.id, people.name, group_concat(numbers.number) 
from people 
inner join numbers on numbers.id = people.id 
group by people.id, people.name 
order by people.name 

然後,您可以用簡單的PHP代碼循環結果集。

+0

我認爲這可能會奏效,但是,它會將所有數字都放入由逗號分隔的單個字段中。除逗號之外是否還有其他分隔符可用? –

+1

是的。 [GROUP_CONCAT語法](http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat)。您甚至可以使用HTML標記作爲分隔符:'group_concat(numbers.number separator'
')'。 –

0

你不應該這樣做。你可以做一個查詢(加入)在表:

select name, number 
from people p, numbers n 
where p.id = n.person_id 
order by name, number; 

,然後就一個循環:

$link = mysqli_connect(...); 
$query = 'select name, number from people p, numbers n where p.id = n.person_id order by name, number'; 

if ($result = mysqli_query($link, $query)) { 
    $person = ''; 
    while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { 
     if ($row['name'] !== $person) { 
      $person = $row['name']; 
      echo $person; 
     } 

     echo $row['number']; 
    } 
} 
1

這取決於,你可能有時間就來了解一下。如果您的數據庫與您的Web服務器位於不同的計算機上,那麼執行多個查詢就會導致很多網絡轉向,因此通常需要更長的時間。但是,如果數據庫服務器與Web服務器位於同一臺計算機上,則這可能不是問題。

還要考慮查找數組中的數字所需的時間。作爲一個數組,你正在做一個線性的O(N)搜索。如果你可以把它放在散列表中,查找速度會快得多,而且這兩種查詢方法可能會更快,但如果你花費大量時間在數組中查找答案,則不會。

使用連接將其放入一個查詢中可能會最快,因爲數字將與人員關聯,具體取決於您要將數據存儲到您的foreach循環中以訪問哪個容器結構。

相關問題