我有一个表(“演示文稿”),其中包含以下列:
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”等...我需要将这些信息附加到这些扬声器上。
提前感谢帮助像我一样的大菜鸟。)
答案 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_Speaker
:PresentationId, 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脚本中进行复杂的处理......