0

我试图弄清楚当您与自身交叉连接表时如何从交叉连接中引用某些列。整个交叉连接表也被赋予了一个别名,这就是为什么我无法访问列名的原因,因为它也与另一个子查询自然连接。这是代码:

select q0.sid, q0.sname 
from (buys t1 cross join student s3 cross join student s4) q0 natural join 
     (select s5.sid, s5.sname, s6.sid, s6.sname, t3.sid, t3.bookno                                                                      
      from buys t2 cross join student s5 cross join student s6 cross join buys t3                                                                       
      where t2.sid = s5.sid and t3.bookno = t2.bookno) q1
where t1.sid = s3.sid;

问题在于尝试比较 t1.sid 和 s3.sid 的“where”子句,因为 q0.sid 不明确。如何从交叉连接访问这些列?

4

2 回答 2

0

连接是标准 SQL 的一个奇怪之处,它很少有用且非常棘手NATURAL我根本不会使用它。

连接条件中的USING子句几乎一样短且不易出错(以防基础表中的列发生更改或您编辑FROM查询列表)。一些 SQL 专业人士甚至不鼓励使用该USING子句,因为它比更显式的子句更容易中断ON。我不和他们在一起。

q0在您的特定查询中,派生表q1具有重复的列名,这使得无法使用NATURAL连接 - 以及任何引用模棱两可的列名的尝试。q0.sid, q0.sname这包括外部列表中的模棱两可的引用SELECT(表student在 中包含两次q0)。此外,SELECT子查询中的列表q1没有任何用途,列没有在任何地方使用。

您的查询在多个地方被破坏,您已经重写它。您的问题应该首先描述查询应该实现的目标、确切的表定义和 Postgres 版本。

于 2017-11-02T04:22:08.333 回答
0

在教授的帮助下,我找到了答案。您必须使用 With 语句粗暴地重命名每个列名。所以它会是这样的:

with e1 as (select t1.sid as t1sid, t1.bookno as t1bookno,
                   s1.sid as s1sid, s1.sname as s1sname,
                   s2.sid as s2sid, s2.sname as s2sname
            from buys t1 cross join student s1 cross join student s2),
     e2 as (select t1.sid as t1.sid, etc as etc) 

这只是重命名您需要的每一列的一种残酷方法,但它确实有效。抱歉,我没有在问题中指定我试图做的是直接转换为 SQL 中的关系代数。感谢任何试图提供帮助的人!

于 2017-11-03T03:01:42.727 回答