【问题标题】:How to use ConcatRelated() on a many-to-many relationship如何在多对多关系上使用 ConcatRelated()
【发布时间】:2017-06-27 01:00:37
【问题描述】:

作为个人教育实验,我正在为想象中的动物收容所建立一个数据库。总的来说,我对 SQL 和数据库很陌生。

任务:在动物收容所数据库中查找宠物的所有主人。

我有三个表:Pets、Owners 和 Pets2Owners。主人可以拥有一只或多只宠物,宠物可以拥有一只、多只或没有主人。表格如下所示:

Pets
+--------+----------+
| ID     | Name     |
+--------+----------+
|      1 | Opal     |
|      2 | Fuzzy    |
|      3 | Angel    |
|      4 | Peewee   |
|      5 | Spike    |
+--------+----------+

Owners
+----------+--------+
| ID       | Name   |
+----------+--------+
|        1 | Shy    |
|        2 | Belle  |
|        3 | Velvet |
|        4 | Brilla |
+----------+--------+

Pets2Owners
+----+--------+----------+
| ID | Pet_ID | Owner_ID |
+----+--------+----------+
|  1 |      1 |        2 |
|  2 |      2 |        1 |
|  3 |      3 |        1 |
|  4 |      5 |        3 |
|  5 |      5 |        4 |
+----+--------+----------+

因此,从 Pets2Owners 中,我们看到宠物 #3(Angel)归所有者 #1(Shy 女士)所有,宠物 #5(Spike)归所有者 #3 和 4(Velvet 和 Brilla)所有,宠物 #4 (Peewee) 不属于任何人。

我对 SQL 缺乏经验,我不确定这是否可行,但有没有一种方法可以在不复制宠物的情况下进行单个查询,为我提供有关宠物和主人的所有信息,如下所示:

+--------+--------+
|  Pets  | Owners |
+--------+--------+
| Opal   | Belle  |
| Fuzzy  | Shy    |
| Angel  | Shy    |
| Peewee | (none) |
| Spike  | Velvet |
|        | Brilla |
+--------+--------+

本质上,我想要一种将所有三个表中的信息合并为一个的方法。我尝试过使用连接,但它们给我留下了重复的条目(例如,Spike 的两行,一个与所有者 Velvet,另一行与所有者 Brilla)。

或者,是否可以进行查询以返回特定宠物的所有所有者,如下所示:

Spike's Owners
+--------+
| Owners |
+--------+
| Velvet |
| Brilla |
+--------+

我可以使用它来实现相同的目标并列出特定宠物的所有所有者(尽管我不确定 SQL 是否有变量可以让我对变量 PetName 进行单个查询,然后重复它任意名称)

【问题讨论】:

  • 您使用的是什么数据库?请适当标记。
  • 哦,对不起! MS Access(我知道,可能不是 SO 上最受欢迎的东西)
  • 您不能执行返回奇数行的查询(例如,您对 Spike 表示想要的)。在您的前端报告或视图中执行此操作。
  • @KenWhite 这正是我所期待的。我应该关闭/删除问题吗?
  • 您可以使用ConcatRelated() 像这样创建单行:| Spike | Velvet, Brilla | -- 参见stackoverflow.com/a/13280353/3820271

标签: sql ms-access group-concat


【解决方案1】:

你可以使用 Allen Browne 的函数ConcatRelated() 来创建这样的单行:

| Spike | Velvet, Brilla |

ConcatRelated() 专为一对多关系而设计。由于您有多对多,因此您需要一个将宠物 ID 与所有者名称相结合的中间查询:

SELECT Pets2Owners.Pet_ID, Owners.OwnerName
FROM Pets2Owners INNER JOIN Owners ON Pets2Owners.Owner_ID = Owners.ID;

我将此查询称为Pet_OwnerNames

那么ConcatRelated()就直截了当:

SELECT Pets.PetName, 
       ConcatRelated("OwnerName", "Pet_OwnerNames", "Pet_ID = " & ID) AS Owners
FROM Pets;

结果:

+---------+----------------+
| PetName |     Owners     |
+---------+----------------+
| Opal    | Belle          |
| Fuzzy   | Shy            |
| Angel   | Shy            |
| Peewee  |                |
| Spike   | Velvet, Brilla |
+---------+----------------+

【讨论】:

    【解决方案2】:
    SELECT Pets.Name AS Pets, Owners.Name AS Owner
    FROM Pets2Owner INNER JOIN Pets ON Pets2Owner.[Pet Id] = Pets.[id]
    INNER JOIN Owners ON Pets2Owner.[Owner Id] = Owners.[id]
    

    在你掌握了 JOINS 之后, 尝试查看 Access 的参数:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 2012-02-27
      相关资源
      最近更新 更多