2012-03-19 38 views
1

我有一個表(「簡報」)與這些列:如何通過PHP訂購三列(具有類似信息)?

PresentationTitle | Speaker1 | Speaker2 | Speaker3 

這個偉大工程,列出所有演講的標題是這樣的對我的「演示」頁:

Presentation Number One 
    by: 
    John Smith 
    Pocahontas Smith 
    John Rolfe 

Presentation Number Two 
    by: 
    Grandmother Willow 

Presentation Number Three 
    by: 
    Chief Powhatan 
    Kocoum Derpyderpderp 

但現在,對於我的「發言人」頁面,我需要按字母順序列出所有發言人 - 彼此獨立。像這樣:

Chief Powhatan 
Grandmother Willow 
John Rolfe 
John Smith 
Kocoum Derpyderpderp 
Pocahontas Smith 

這樣做的最佳方法是什麼?

另外要注意的 - 在我的現實生活中的表中,揚聲器1列有許多附加到它 - 「中間名」多列,「姓氏」,「爆頭」,「時代」 ......和音箱2有「middlename2」,「lastname2」,「headshot2」等等。我需要將這些信息保留給這些發言者。

預先感謝幫助一個大的小白和我一樣:)

+0

你有什麼嘗試?嘗試失敗的地方在哪裏?你的具體編碼問題是什麼? – 2012-03-19 18:21:32

+0

您是否在問如何使用Speakers頁面的單獨SQL查詢或者如何對已從表中提取的PHP中的數組進行排序?向我們展示一些代碼。 – 2012-03-19 18:28:26

回答

3

你應該重新考慮你的數據庫設計。更好的表格佈局將是更多的東西一樣:

CREATE TABLE presentations (
    presentationID INT, 
    presentationTitle VARCHAR(200), 
    PRIMARY KEY (presentationID) 
); 

CREATE TABLE speakers (
    speakerID INT, 
    firstName VARCHAR(32), 
    middleName VARCHAR(32), 
    lastName VARCHAR(32), 
    headshot BLOB, 
    age TINYINT UNSIGNED, 
    PRIMARY KEY (speakerID) 
); 

CREATE TABLE presentationSpeakers (
    presentationID INT, 
    speakerID INT 
); 

然後,你可以做一個查詢這樣的名字列出從特定演示按字母順序排列的所有發言者:

SELECT 
    s.firstName, 
    s.lastName 
FROM 
    presentationSpeakers ps 
    INNER JOIN presentations p ON ps.presentationID = p.presentationID 
    INNER JOIN speakers s ON ps.speakerID = s.speakerID 
WHERE 
    p.presentationTitle = 'Presentation Number One' 
ORDER BY 
    s.firstName, s.lastName 

或查詢像這樣簡單的通過第一名稱的字母順序排列的所有發言者:

SELECT firstName, lastName FROM speakers ORDER BY firstName, s.lastName 

這是許多原因更好。每個演講者都有一堆額外的列很難處理(這是你現在遇到的麻煩),再加上你可能會有很多列可能無法使用(取決於揚聲器的數量),這可能會浪費空間,另一個重要原因......如果您的演講報告的發言人多於專欄的話,該怎麼辦?

我的方式更加靈活,更容易執行簡單的操作(如排序)。您可以爲每個演示文稿設置任意數量的揚聲器,並且沒有浪費的空間佔用未使用的列。

+0

另外,如果有人在多個演示文稿中發言,那麼原始方式將會複製您不會的數據。當然,這兩個(或更多)數據集的所有固有風險不同步......但是,重新設計是這樣做的最佳方式。 – Chris 2012-03-19 18:41:50

+1

@Chris:另一個非常有用的觀點。特別是如果你正在存儲爆頭(我認爲這是一張照片,存儲爲BLOB)。數據重複問題可能變得更加重要。 – Travesty3 2012-03-19 18:44:02

+0

非常感謝!現在我正在重組表格,但我已經可以告訴大家,這會比我的原始設計要好得多。 :) – AnnaBlabber 2012-03-21 18:44:31

0

什麼可能是一個相當簡單的方法你是列出任何數據是在HTML表格適用於「揚聲器」,然後讓該表排序。

我已經使用了here的JavaScript來使我的HTML表可排序,並且它工作得非常好。還有其他的可排序HTML表格的實現。

這樣,你不必更動使得MySQL的視圖和/或過程,你不必做複雜的處理在你的PHP腳本...

3

你的問題是:

什麼是做到這一點的最好方法是什麼?

那麼,主要的問題在於你的桌子的設計。

如果你有這樣的表:PresentationTitle, Speaker1, Speaker2, Speaker3

不是所有的演示有3個揚聲器,然後,你有一個糟糕的設計:)

你應該有一個Presentation表是這樣的:PresentationId, PresentationTitle

而且另一個表名爲Speakers這樣的:SpeakerId, SpeakerName

然後,因爲你可以有一個揚聲器去多個演示文稿並且一個演講者與多個演講者之間有多對多的關係,並且根據經驗,總是會產生一個新表格。

在這種情況下,這將是該表Presentation_SpeakerPresentationId, SpeakerId(兩場是在PK)

所以,現在你正在做的事情「的最好辦法」 :)你怎麼能取回所有揚聲器?只要運行這個查詢:

select * from speakers 

現在,如果你不想做前面的步驟做的事情以正確的方式,我只是回答你的問題,從那些3個揚聲器列讓所有發言者:

(select speaker1 Speaker from presentations) 
union 
(select speaker2 from presentations) 
union 
(select speaker3 from presentations) 
order by Speaker 

重複的揚聲器將被刪除。

PS:我沒有得到你的「現實生活中的例子」:

的揚聲器1列連接到它

其它更多的列那你是什麼意思?

+1

他意味着每個揚聲器都有那些列(例如middlename),它們存儲爲'Speaker1_Middlename','Speaker2_Middlename'等。我想。因此,您的新設計只需將這些列添加到揚聲器表中即可排序。另外,如果發言者的排序很重要(例如,一個主發言者),則'Presentation_Speaker'表可能需要訂單列。 – Chris 2012-03-19 18:44:09

+0

哦,好的。然後,設計比我想象的更糟糕,因爲當同一位演講者參加2個演講時,會重複大量信息。是的,那麼所有的揚聲器信息都應該移到'Speakers'表中。 – 2012-03-19 18:50:40

+0

感謝您的建議!我最初把它全部放在一張表中,因爲1)我是一個noob,2)所以我的非編碼員同事可以很容易地通過MySQL進行演示,3)有些名字經常拼寫不同(如「John」vs. 「喬納森博士」)。但這絕對聽起來像我不得不打破桌子。 – AnnaBlabber 2012-03-19 19:40:39

2

您需要重構表格。你幾乎在那裏,但你需要一些規範化。取而代之的揚聲器1,揚聲器...等,把你的音箱在一個單獨的表:

speaker: 
speaker_id | firstname | lastname | headshot ... (etc) 

然後演示表應該基本上只是與呈現相關聯列:

presentation: 
presentation_id | title | location ...(etc) 

然後加入吧一起你需要一個連接表與結構

presentation_speaker: 
presentation_id | speaker_id 

所以引用的ID一樣,你可以通過執行獲得爲了所有發言者:

SELECT * FROM speaker ORDER BY lastname, firstname 

編輯 如果你想用於演示的特定組揚聲器查詢

SELECT * FROM presentation_speaker ps 
    JOIN speaker s ON s.speaker_id=ps.speaker_id 
    WHERE ps.presentation_id IN ($pres1, $pres2, ... etc) 
    ORDER BY s.lastname, s.firstname 

您的原始輸出是有點困難,但不是太糟糕。如果您沒有噸然後做一個額外的查詢在循環中並沒有那麼糟糕:

$query1 = "SELECT * FROM presentation"; 
$res = mysql_query($query1); 

if(mysql_error($res)) { 
    die(mysql_error($res)); 
} 

$presentations = array(); 

while($row = mysql_fetch_row($res)) { 
    $row['speakers'] = array(); 
    $query2 = "SELECT * FROM presentation_speaker ps 
     JOIN speaker s ON ps.speaker_id = s.speaker_id 
     WHERE sp.presentation_id=" . mysql_real_escape_string($row['presentation_id']); 

    $res2 = mysql_query($query2); 
    if(mysql_error($res2)) { 
     die(mysql_error($res2)); 
    } 

    while($speaker = mysql_fetch_row($res2)) { 
     $row['speakers'][] = $speaker; 
    } 

    $presentations[] = $row; 
} 

有了,你會最終有一個數據結構,看起來像:

Array(
    'title' => 'Presentation title', 
    'location' => 'Some place', 
    'speakers' => 
     Array(
      'firstname' => 'Quazi', 
      'lastname' => 'Moto', 
      'headshot' => 'quazi.jpg' 
     ), 
     Array(
      'firstname' => 'Slarty', 
      'lastname' => 'Bartfast', 
      'headshot' => 'dontpanic.jpg' 
     )  
)