我想以一对多关系创建视图。这是我的关系:
(a -* b)
(a -* c)
Run Code Online (Sandbox Code Playgroud)
我想创建一个视图以包含以下数据:
我不想要类似(a1,b1,c1-a1,b1,c2,...)之类的东西。我希望数据为:
(ID,DESCRIPTION1,DESCRIPTION2,DESCRIPTION3)
在一个记录中。
例如,如果在表a中我有数据:(1,2,3)
在表b中我有(a在fk为1的10,11,12和a在fk为2的20,21,22中)
并且在表c中我有(100,101,102,其中fk等于1)
我想要这样的结果在一排:
1,10,11,12,100,101,102为1
像这样的2,3,...
我认为我需要“单行子查询示例”,但我找不到任何示例,您能帮我吗?
如何创建此视图?
正如我在评论中指出的,用于描述关系的符号不是标准的。
我认为这意味着您有一个关系 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)
Run Code Online (Sandbox Code Playgroud)
如果您遵循 CJ 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 | |
| | | | +------+------+ | +------+------+ |
+------+------+------+------------------+-----------------+
Run Code Online (Sandbox Code Playgroud)
这是表达你所追求的东西的一种非常简洁的方式。不幸的是,据我所知,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
Run Code Online (Sandbox Code Playgroud)
你说:
我希望数据是:
(ID、描述 1、描述 2、描述 3)
在一张记录中。
例如,如果表 a 中有数据:(1,2,3)
在表b中我有(10,11,12,a中fk为1,20,21,22,a中fk为2)
在表c中我有(100,101,102,a中的fk为1)
我想要这样的结果在一行中:
1,10,11,12,100,101,102 为 1
根据“我想要数据”语句,您想要一个具有 4 列的视图,但您显示的结果显示了 7 个值 - 因为 B 中有 3 条记录对应于 A 中 ID 为 1 的记录,并且同样,因为 C 中也有 3 条记录。目前尚不清楚 A 的描述 1 中的值是什么 - 它似乎丢失了。如果 B 中有 6 行,C 中有 10 行对应于 A 中的第 1 行,您需要多少列?这与 A 中 ID 为 2 的记录的列数(B 中的 4 行和 C 中的 3 行匹配)有何关系?
如果您请求的结果如下:
1,Note1,{10,11,12},{100,101,102}
Run Code Online (Sandbox Code Playgroud)
如果大括号包围某种列表,那么您的结果确实有四列。此外,如果您的 DBMS 支持 GROUP_CONCAT 操作,您甚至可以编写生成结果的查询。
您将了解到,如果您没有准确表达查询的要求,您将得到准随机结果,或者至少不是您真正想要的结果。当你得到精确表达的查询需求时,整个过程就容易多了。
在支持 GROUP_CONCAT 的系统中,您将使用以下命令获得一个列表:
SELECT B.ID, GROUP_CONCAT(B.Description2) AS Description2
FROM B
GROUP BY B.ID
Run Code Online (Sandbox Code Playgroud)
然后编写将其中两个表达式连接到 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
Run Code Online (Sandbox Code Playgroud)
要将其放入视图中,请应用适当的“CREATE VIEW”前缀。