sql创建一对多关系视图

时间:2010-04-05 05:43:50

标签: sql

我想以一对多关系创建视图。 这是我的关系:

(a -* b)
(a -* c)

我想创建一个包含此数据的视图:

  • a1 - (所有b与a1 +所有c相关,与a1相关)

我不想要像(a1,b1,c1 - a1,b1,c2,...)这样的东西。 我想要数据:

(ID,DESCRIPTION1,DESCRIPTION2,DESCRIPTION3)

在一张唱片中。

例如,如果在表a中我有数据:(1,2,3)

在表b中我有(10,11,12,其中fk为1 in a和20,21,22,fk为2 in a)

并且在表c中我有(100,101,102,其中fk为1 in a)

我想把这样的结果放在一行:

1,10,11,12,100,101,102为1

和2,3这样的事情......

我想我需要“单行子查询示例”,但我找不到任何示例,你能帮助我吗?

如何创建此视图?

1 个答案:

答案 0 :(得分:2)

正如我在评论中所指出的,用于描述关系的符号不是标准的。

我认为这意味着你有一个关系A,它与关系B中的行有一对多关系,并且与关系C中的行有一个单独的一对多关系。

结果关系(视图)理想情况下应该为A中的每个项目都有一行,以及来自B的相应行和来自C的相应行 - 但是不应该有B和C中行的笛卡尔积。在A中的行。

我假设你的关系是:

A(A1, A2, A3) - Primary Key (A1)
B(B1, B2, B3) - Foreign Key (B1) References A(A1)
C(C1, C2, C3) - Foreign Key (C1) References A(A1)

如果您遵循C J Date的视图,您需要的是具有一对RVA - 关系值属性的视图。也就是说,您将拥有类似于:

的表结构
+------+------+------+------------------+-----------------+
|      |      |      |  +------+------+ | +------+------+ |
|  A1  |  A2  |  A3  |  |  B2  |  B3  | | |  C2  |  C3  | |
|      |      |      |  +------+------+ | +------+------+ |
+------+------+------+------------------+-----------------+
|      |      |      |  +------+------+ | +------+------+ |
|      |      |      |  |  b21 |  b31 | | |  c42 |  c13 | |
|  a11 |  a21 |  a31 |  |  b22 |  b32 | | |  c52 |  c23 | |
|      |      |      |  |  b23 |  b33 | | |  c62 |  c13 | |
|      |      |      |  |      |      | | |  c72 |  c23 | |
|      |      |      |  +------+------+ | +------+------+ |
+------+------+------+------------------+-----------------+

这是一种非常巧妙的表达方式。不幸的是,AFAIK,SQL不支持这种表示法。最近的方法可能是两个独立的外连接,这往往会产生很多行(在示例中为12):

SELECT A.A1, A.A2, A.A3, B.B2, B.B3, C.C2, C.C3
  FROM A LEFT OUTER JOIN B ON A.A1 = B.B1
         LEFT OUTER JOIN C ON A.A1 = C.C1

你说:

  

我想要数据:

     

(ID,DESCRIPTION1,DESCRIPTION2,DESCRIPTION3)

     

在一张唱片中。

     

例如,如果在表a中我有数据:(1,2,3)

     

在表b中我有(10,11,12,其中fk为1 in a和20,21,22,fk为2 in a)

     

并且在表c中我有(100,101,102,其中fk为1 in a)

     

我想把这样的结果放在一行:

     

1,10,11,12,100,101,102为1

根据“我希望数据是”语句,您想要一个包含4列的视图,但您显示的结果显示7个值 - 因为B中有三条记录对应于ID为1的记录A,同样因为C中也有三条记录。目前尚不清楚A中的Description1中有什么价值 - 它似乎缺失了。如果B中有6行而C中有10行与A中的第1行相对应,那么您想要多少列?这与A中ID为2的记录的列数有何关系(B中有4行,C中有3行匹配)?

如果您要求的结果如下:

 1,Note1,{10,11,12},{100,101,102}

括号围绕某种列表,那么你的结果确实有四列。此外,如果您的DBMS支持GROUP_CONCAT操作,您甚至可以编写产生结果的查询。

您将了解到,如果您没有准确地表达查询的要求,则无论如何都会得到准随机结果 - 或者除了您真正想要的结果之外的结果。当您准确地表达查询要求时,整个过程就会容易得多。

在支持GROUP_CONCAT的系统中,您将使用以下命令获取一个列表:

SELECT B.ID, GROUP_CONCAT(B.Description2) AS Description2
  FROM B
 GROUP BY B.ID

然后,您将整个查询编写为将其中两个表达式连接到A:

SELECT A1.ID, A1.Description AS Description1,
       B2.Description2, C3.Description3
  FROM A AS A1 LEFT OUTER JOIN
       (SELECT B.ID, GROUP_CONCAT(B.Description) AS Description2
          FROM B
         GROUP BY B.ID) AS B2 ON A1.ID = B2.ID
         LEFT OUTER JOIN
       (SELECT C.ID, GROUP_CONCAT(C.Description) AS Description3
          FROM C
         GROUP BY C.ID) AS C3 ON A1.ID = C3.ID

要将其添加到视图中,请应用相应的“CREATE VIEW”前​​缀。