如何通过PHP按三列(具有类似信息)订购?

时间:2012-03-19 18:18:25

标签: php mysql

我有一个表(“演示文稿”),其中包含以下列:

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

最好的方法是什么?

另一个注意事项 - 在我的真实表中, speaker1 列附加了更多列 - “middlename”,“lastname”,“headshot”,“age”.. 。和 speaker2 有“middlename2”,“lastname2”,“headshot2”等...我需要将这些信息附加到这些扬声器上。

提前感谢帮助像我一样的大菜鸟。)

4 个答案:

答案 0 :(得分: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

这对于很多的原因更好。为每个扬声器添加一堆额外的列将很难处理(这是你现在遇到的麻烦),而且你将有大量的列可能无法使用(取决于扬声器的数量),这可能会浪费空间,另一个重要原因......如果你的演讲中有更多的扬声器而不是你的专栏怎么办?

我的方式更灵活,更容易执行简单的操作(如排序)。每个演示文稿可以有任意数量的扬声器,并且没有浪费的空间占用未使用的列。

答案 1 :(得分: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:我没有得到你的“现实生活中的例子”:

  

speaker1列附加了更多列

你是什么意思?

答案 2 :(得分:2)

您需要重组表格。你几乎就在那里,但你需要一些规范化。而不是扬声器1,扬声器2等,将您的扬声器放在一个单独的表中:

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

然后你的演示表基本上应该只有与演示文稿相关的列:

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

然后要将它们连接在一起,您需要一个引用ID的连接表

presentation_speaker:
presentation_id | speaker_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'
       )    
)

答案 3 :(得分:0)

对您来说,一个相当简单的方法是在HTML表格中列出适用于“扬声器”的任何数据,然后使该表可排序。

我使用了here中的JavaScript来使我的HTML表格可以排序,而且效果非常好。还有其他可排序HTML表的实现。

这样你就不必乱用MySQL视图和/或程序,而且你不必在PHP脚本中进行复杂的处理......