Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL左连接奇怪的语法错误?_Sql_Syntax_Join_Ms Access 2007 - Fatal编程技术网

SQL左连接奇怪的语法错误?

SQL左连接奇怪的语法错误?,sql,syntax,join,ms-access-2007,Sql,Syntax,Join,Ms Access 2007,==问题=== 我在3个表上使用了一个左连接SQL表达式。尝试运行MS ACCESS 2007时,我从中收到一个意外错误“不支持联接表达式” ==详细信息=== 这些桌子都是连在一起的 家长:处于最高级别 孩子1:父母的孩子 子女2:父母的子女 孙辈1:孩子的孩子1 这是导致错误的SQL表达式: SELECT * FROM ((grandchild1 AS gc LEFT JOIN child1 AS c1 ON gc.child1_id=c1.id) LEFT JO

==问题===

我在3个表上使用了一个左连接SQL表达式。尝试运行MS ACCESS 2007时,我从中收到一个意外错误“不支持联接表达式”

==详细信息===

这些桌子都是连在一起的

  • 家长:处于最高级别
  • 孩子1:父母的孩子
  • 子女2:父母的子女
  • 孙辈1:孩子的孩子1
这是导致错误的SQL表达式:

SELECT *
FROM ((grandchild1 AS gc
      LEFT JOIN child1 AS c1 ON gc.child1_id=c1.id)
      LEFT JOIN parent AS p ON c1.parent_id=p.id)
      LEFT JOIN child2 AS c2 ON (p.id=c2.parent_id 
                                 AND c2.start<=gc.time AND gc.time<=c2.stop)
选择*
FROM((1)作为gc
在gc.child1上将child1作为c1左连接(id=c1.id)
在c1上以p的形式左键连接父项。父项(id=p.id)
左连接child2作为c2打开(p.id=c2.parent\u id

和c2.start通常,您编写的连接如下:

SELECT * FROM grandchild1 AS gc
LEFT JOIN child1 AS c1 ON gc.child1_id=c1.id
LEFT JOIN parent AS p ON c1.parent_id=p.id
LEFT JOIN child2 AS c2 ON (p.id=c2.parent_id AND c2.start<=gc.time AND gc.time<=c2.stop)
从1中选择*作为gc
将child1作为c1在gc上左键联接。child1_id=c1.id
在c1上以p的形式左键连接父项。父项id=p.id
左键连接child2作为c2 ON(p.id=c2.parent_id和c2.start查看

看起来有点特别,在ON子句中只允许一个操作。 另外,对于access 2007,您必须嵌套您的联接。
此外,我认为日期范围应该在WHERE子句中

试试这个:

SELECT *
FROM grandchild1 AS gc
LEFT JOIN (

  child1 as C1 LEFT JOIN (

      parent as P LEFT JOIN child2 as C2 ON P.id = C2.parent_id 

  ) ON c1.parent_id = P.id

) ON gc.child1_id = C1.id

WHERE 
    c2.start <= gc.time AND gc.time <= c2.stop
选择*
从1开始作为gc
左连接(
child1作为C1左联接(
父对象作为P左连接子对象2作为P.id=C2.parent\u id上的C2
)在c1.parent_id=P.id上
)关于gc.child1_id=C1.id
哪里

c2.start在非等联接中,表的顺序必须相同。而不是这样:

  c2.start<=gc.time AND gc.time<=c2.stop
中间是包含双方的,所以我认为它完全等同于您最初的标准

尽管如此,我认为问题在于你定义的连接有三个条件,其中一个适用于一对表,另外两个适用于另一对表。你的第一个条件,p.id=c2.parent_id,将c2连接到p,而你的第二对非相等条件将c2和gc连接起来。这些类型的连接是非常复杂的y

我建议使用Access QBE将连接定义为相等连接,然后调整连接的SQL使其成为非相等连接


或者,在WHERE子句中应用日期/时间条件可能更简单,即作为隐式联接。

使用WHERE条件并保留ON条件,以实现其目的,即指定如何联接表而不是过滤数据。您的方法也更难读取,并且不总是适用于r实例将方法3的WHERE条件移动到ON子句中,并亲自查看

drop table if exists t1;
create table t1(id int unsigned not null primary key);

drop table if exists t2;
create table t2(id int unsigned not null primary key);

insert into t1 (id) values (1),(2),(3),(5),(4),(6);
insert into t2 (id) values (2),(4),(6);

-- method 1:
select t1.id from t1 where id not in (select id from t2);

-- method 2:
select t1.id from t1 where not exists (select id from t2 where t1.id = t2.id);

-- method 3:
select
 t1.id
from
 t1
left outer join t2 on t1.id = t2.id
where
 t2.id is null;

Access/Jet/ACE需要参数。Access QBE会将它们放在需要的位置。忽略它们,它会抱怨,否则您可能无法获得预期的结果。谢谢,但是的,我在其他表达式中尝试了这个方法,一开始没有在每个连接周围加括号,但Access似乎不接受它…我想这是您的访问谢谢David。使用QBE正如您所说,让access构造连接提供了解决方案。我尝试用左连接替换它使用的内部连接,但这导致错误再次出现。它似乎也不喜欢我将ON子句放在括号之间(我认为我实际上在帮助它)但是它似乎在ON子句中的表顺序方面没有问题。我想使用内部联接确实更有意义,所以我会坚持下去。我很高兴它被解决了。这确实让我感到QBE的巨大优势。它确实可以让您更轻松地获得Jet/ACE的正确语法。谢谢您的建议。我我应该使用这个,但是我加入的表是在FROM子句中创建一个或多个表,所以我真的不能使用WHERE子句(很抱歉,我的示例没有给出,因为我试图保持它的简单性)“不能”可能不是真的。我想这会很不方便,因为大多数显式连接都可以转换为等价的WHERE子句(隐式连接),而且大多数数据库引擎都会完全相同地优化等价语句,我不相信这一点。我想检查查询优化以确定(Google Jet SHOWPLAN将了解如何进行优化)。
  c2.start<=gc.time AND gc.time<=c2.stop
  c2.start<=gc.time AND c2.stop>=gc.time
  gc.time>=c2.start AND gc.time<=c2.stop
  gc.time BETWEEN c2.start AND c2.stop
drop table if exists t1;
create table t1(id int unsigned not null primary key);

drop table if exists t2;
create table t2(id int unsigned not null primary key);

insert into t1 (id) values (1),(2),(3),(5),(4),(6);
insert into t2 (id) values (2),(4),(6);

-- method 1:
select t1.id from t1 where id not in (select id from t2);

-- method 2:
select t1.id from t1 where not exists (select id from t2 where t1.id = t2.id);

-- method 3:
select
 t1.id
from
 t1
left outer join t2 on t1.id = t2.id
where
 t2.id is null;