SQL/PSQL 在交叉连接相同的 table 后引用 where 子句中的列名

SQL/PSQL Referencing column names in the where clause after cross joining the same table with each other

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

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 是不明确的。如何从交叉连接访问这些列?

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

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

在您的特定查询中,派生的 tables q0q1 具有重复的列名,这使得无法使用 NATURAL 连接 - 以及 any 试图引用 不明确的列名称 。这包括外部 SELECT 列表中的模糊引用 q0.sid, q0.sname(table studentq0 中包含两次)。此外,子查询 q1 中的 SELECT 列表没有任何用处,列未在任何地方使用。

您的查询在多个地方被破坏,您已经重写了它。您的问题应该以查询应该实现的内容、确切的 table 定义和 Postgres 版本的描述开始。

感谢教授的帮助,我找到了答案。您必须使用 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 中的关系代数。感谢任何试图提供帮助的人!