【问题标题】:Can I display one to many results in results table?我可以在结果表中显示一对多的结果吗?
【发布时间】:2012-09-23 08:56:26
【问题描述】:

我有一张person 的桌子和一张language 的桌子。每个人最多可以说 4 种语言。我的客户想要搜索会说话的人,例如Spanish

我的问题是结果表目前没有名为Language 的列,因为它们会说多个。我可以只显示第一个,但隐藏他们说的其他语言会产生误导。

表格可以为每种语言提供一列,如果它们没有全部 4 种语言,请填写 NULL,即:

Language 1
Language 2
Language 3
Language 4

但这似乎很草率。

我考虑过在一个列中列出所有语言,使用逗号分隔的列表,但这对于按字母顺序对列进行排序很有用。

目前,我不得不告诉我的客户,结果表只能显示该人拥有其中之一的列(1 到 1),即namelocation、母语等。只有当客户点击那个人,它会显示他们所有的语言。

有谁知道是否有解决此问题的通用方法?希望这是有道理的

我确实有一个关联表。问题是我的搜索会返回

joe bloggs,哥谭市,西班牙语

然后

joe bloggs,哥谭市,法语

在下一行 - 但是同一个人在表中列出了两次。当我将其限制为每个名称一个条目时,我只会得到“joe bloggs, gotham city, spanish”。现在我不知道他还会说法语。这更清楚了吗?

【问题讨论】:

  • 你的表结构到底是什么,你的查询是什么?您想要一个包含所有人员语言的一行结果集吗?
  • 请检查如何标记答案。如果你的回答率不好,很多人以后不会回答你的问题。

标签: mysql


【解决方案1】:

您应该有一个包含两个字段的连接表:人员和语言。每个人每种语言应该有一行,所以如果一个人会说四种语言,那么这个用户将有四行。

此表的主键将包含两个字段。

然后,要获得说西班牙语的人的列表,您需要这样的查询

select people.name
from people inner join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id
where languages.name = 'Spanish'

以及所有会说某种语言的人的名单

select people.name, languages.name
from people inner join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id 

现在是所有人的列表,无论他们是否说某种语言

select people.name, languages.name
from people left join p2l
on people.id = p2l.person
inner join languages
on p2l.language = languages.id 

【讨论】:

  • 嗨。我有这个。请参阅我添加到原始问题中的额外文本。当搜索条件中未定义任何语言时,问题就出现了——它将返回他们的所有语言,并最终在结果表中为该人提供 4 个条目。对不起,如果我不清楚
  • 如果一个人不会说任何语言,那么 p2l 表中将没有行。在这种情况下,您需要“左连接”而不是“内连接”
【解决方案2】:

再想一想,看来你有以下选择

  1. 使用 Christophe 和我建议的简单连接/链接/关联表,然后在调用 SQL 的程序中处理数据。这是最简单的路线。
  2. 维护一个以逗号分隔的语言列表以及连接表。连接表将允许您回答诸如“谁说西班牙语”之类的查询,而列表将使您能够打印出每个人的语言列表。维护此列表将是一个问题。
  3. 使用 Ravindra 的“每种语言的专用字段”方法;每次需要新语言时,都必须更改字段结构,因此非常不推荐这种方法。
  4. 使用交叉表查询;这很难做到,取决于您使用的是哪种 SQL。看这篇文章creating-cross-tab-queries-and-pivot-tables-in-sql

在我的选择中,选项 1 是最好和最简单的。 SQL 擅长做的事,但不擅长做的事,因此最好采用 SQL 的最佳部分,并用声明性语言的最佳部分围绕它们。

【讨论】:

  • 谢谢。我选择了选项 1 - 并且不会在结果表中有一列,该列的人可以拥有多个项目。无论如何,这有点多余 - 如果我的客户将她的搜索过滤到说西班牙语的人,我们知道所有返回的结果都可以说西班牙语,所以不需要在结果表中的每一行都显示“西班牙语”的列。至少,这就是我向客户“出售”我的解决方案的方式
【解决方案3】:

因此,解决此问题的传统方法是创建一个称为关联表的东西,它具有人员表和语言表的外键。这使您可以添加任意数量的语言(包括零)。然后,您可以跨这些表连接以查找所有使用特定语言的用户。

这可能有助于如何构建数据库:http://en.wikipedia.org/wiki/First_normal_form 有更高的范式,但这将帮助您解决当前的问题。

【讨论】:

  • 请查看我添加到问题中的附加评论
  • 那你不能在服务器端处理你的查询结果吗?在数据库层做这件事真的很痛苦。
  • 我可以,我只是想知道是否有一种优雅的方式来显示返回超过 1 个结果的一对多关系的结果。我想我应该把它放在我最初的问题中。一种避免每个人重复行的方法
  • 您可以使用相关子查询来获取一个人知道的 4 种语言,按字母顺序排列,为额外的位置填充空值。但它不会是高性能的,而且写起来会很痛苦。
  • 是的,我怀疑这一点 - 没有一个优雅的解决方案。我将不得不显示一个人可以拥有多个列的列。这似乎是一个常见的问题,会有一个解决方案
【解决方案4】:

创建两个表
有cloumns的人-person_id,person_name & more如果你愿意。
创建另一个表-具有列的语言-person_id,lang1,lang2,lang3,lang4
制作person_id as foreign key
现在当你想访问语言时,只需通过比较 person_id 来获取它们

 SELECT p.person_id
FROM person p, language l
WHERE p.person_id = l.person_id;

【讨论】:

  • 必须添加新语言时会发生什么?这是一个非常不灵活的解决方案,应该不惜一切代价避免。这违反了第一范式 - 没有重复组。
  • @Ravindra bagaleji: aare dhanyawad kasala...eka marathi manasa la downvote kelela mi baghu shakat nahi...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多