我正在开发一个包含人员的MySQL数据库。我的问题是,(我会简化以表明我的观点):
我有三张桌子:
Persons(id int, birthdate date)
PersonsLastNames(id int, lastname varchar(30))
PersonsFirstNames(id int, firstname varchar(30))
id是公共密钥。有姓氏和名字的单独表格,因为一个人可以有许多名字和许多姓氏。
我想创建一个查询,返回所有人,比如一个姓氏。如果我一起去
select birthdate, lastname, firstname from Persons, PersonsLastNames,
PersonsFirstNames where Persons.id = PersonsLastNames.id and
Persons.id = PersonsFirstNames.id and lastName = 'Anderson'
我最终得到一张像
这样的表格1/1/1970 Anderson Steven //Person 1
1/1/1970 Anderson David //Still Person 1
2/2/1980 Smith Adam //Person 2
3/3/1990 Taylor Ed //Person 3
在提出这个时,我想有
1/1/1970 Anderson Steven David
2/2/1980 Smith Adam [possibly null?]
3/3/1990 Taylor Ed [possibly null?]
如果需要为一个人保留多个名字或姓氏,我如何加入表格以在结果集中引入新列?
答案 0 :(得分:1)
SQL不支持查询select-list中的动态列数。您必须根据需要定义尽可能多的列(尽管有*
通配符)。
我建议您将多个名称提取为行,而不是列。然后编写一些应用程序代码来遍历结果集,并做任何你想做的事情来呈现它们。
答案 1 :(得分:1)
简短的回答是,你做不到。您将始终必须选择固定数量的列。但是,您可以使用ON关键字大大改善查询的语法。例如:
SELECT
birthdate,
firstName,
lastName
FROM
Persons
INNER JOIN PersonsLastNames
ON Persons.id = PersonsLastNames.id
INNER JOIN PersonsFirstNames
ON Persons.id = PersonsFirstNames.id
WHERE
lastName = 'Anderson'
GROUP BY
lastName, firstName
HAVING
count(lastName) = 1
当然,我的查询最后会包含一些额外条款,以便只抓住指定了一个姓氏的人,但是你可以随时删除这些。
现在,您可以做的是选择您想要检索的最大数量,并执行以下操作:
SELECT
birthdate,
lastName,
PersonsFirstNames.firstName,
IFNULL(p.firstName,''),
IFNULL(q.firstName,'')
FROM
Persons
INNER JOIN PersonsLastNames
ON Persons.id = PersonsLastNames.id
INNER JOIN PersonsFirstNames
ON Persons.id = PersonsFirstNames.id
LEFT JOIN PersonsFirstNames p
ON Persons.id = p.id
AND p.firstName <> PersonsFirstNames.firstName
LEFT JOIN PersonsFirstNames q
ON Persons.id = q.id
AND q.firstName <> PersonsFirstNames.firstName
AND q.firstName <> p.firstName
GROUP BY
lastName
但我真的不建议这样做。最好的办法是检索多行,然后在你正在使用/开发的任何应用程序中迭代它们。
如果您还不熟悉,请务必在开始之前阅读JOIN类型(左 - 内 - )。希望这会有所帮助。
编辑:在这种情况下,你可能还想考虑一个稍微复杂的GROUP BY子句,例如
GROUP BY
Persons.id, lastName
答案 2 :(得分:1)
您的应用真的是否需要为每个人处理无限的姓/名?我不知道你的具体需求,但这似乎有点极端。无论...
由于您无法真正返回动态数量的列,因此可以执行以下操作:
SELECT birthdate, lastname, GROUP_CONCAT(firstname SEPARATOR '|') AS firstnames
FROM Persons, PersonsLastNames, PersonsFirstNames
WHERE Persons.id = PersonsLastNames.id
AND Persons.id = PersonsFirstNames.id
GROUP BY Persons.id
这将为每个人返回一个具有姓氏的行,其中(无限制)名字由竖线(|
)符号,GROUP_CONCAT函数分隔。
birthdate lastname firstnames
--- --- ---
1970-01-01 00:00:00 Anderson Steven|David
1980-02-02 00:00:00 Smith Adam
1990-03-03 00:00:00 Taylor Ed
答案 3 :(得分:0)
我认为你能做的最接近的事情是Group By Person.Id
,然后进行字符串连接。也许这篇文章会有所帮助:
How to use GROUP BY to concatenate strings in MySQL?