Sql 内部连接的怪物…多部分。。。不能绑定?

Sql 内部连接的怪物…多部分。。。不能绑定?,sql,sql-server-2008,tsql,Sql,Sql Server 2008,Tsql,我有一个T-SQL Server 2008查询: SELECT users.user_id, course_main.course_name, course_main.course_id FROM users, course_main INNER JOIN course_application ON users.pk1 /*(error #1)*/ = course_application.pk1 INN

我有一个T-SQL Server 2008查询:

SELECT users.user_id,
       course_main.course_name,
       course_main.course_id
FROM   users,
       course_main
       INNER JOIN course_application
         ON users.pk1 /*(error #1)*/ = course_application.pk1
       INNER JOIN course_main /*(error #2)*/
         ON course_application.crsmain_pk1 = course_main.pk1
       INNER JOIN course_users
         ON users.pk1 /*(error #3)*/ = course_users.users_pk1
            AND course_main.pk1 = course_users.crsmain_pk1
            AND course_main.pk1 = course_users.child_crsmain_pk1
WHERE  course_users.role = 'P'
       AND ( ( course_main.course_id ) LIKE '%FA2013'
             AND ( course_application.application ) = 'alrn-AtomicLearning_tool' )
       AND ( ( ( course_application.enable_ind ) = 'Y'
                OR ( course_application.visible_ind ) = 'N' )
              OR ( ( course_application.enable_ind ) = 'N'
                    OR ( course_application.visible_ind ) = 'Y' ) ) 
所有的嵌套连接都让我头疼。我希望带查询设计器的SQLServer2008至少能够输入别名,但我想我错了

当我在编辑器中时,在第一个连接中,
users.pk1
会出现一个错误

无法绑定多部分标识符“users.pk1”

我也得到了这个错误:

FROM子句中的对象“course\u main”和“course\u main”具有相同的公开名称。使用相关名称来区分它们

我对别名知之甚少,也知道如何将它们放入SQL中以完成非常非常基本的任务,但我只想把自己弄糊涂,弄得一去不返。我已经读了所有关于别名的书,但只是不知道在这个复杂的连接中应该在哪里正确使用它们。请帮忙

多谢各位

编辑:我真的不知道如何陈述我的意图。基本上,我正在尝试从我选择的所有表中获取3列。要获得正确的数据,表之间必须匹配键和所有项。在SQLServer2008中,我选择了所有具有关系的表。我以前运行过查询,我只从course_main和course_application表中进行选择。因为它们之间有着直接的关系,所以实现这一点只需要一个连接。添加这两个额外的表(users和course_users定义哪些用户在数据库中作为特定角色与其他表中的键相匹配)使它变得更加复杂

以下是四个表的模式:


我建议您在表格中始终使用别名,如下所示

select
   u.user_id,
   cm.course_name,
   cm.course_id
from users as u
   cross join course_main as cm
   inner join course_application as ca on u.pk1 /*(error #1)*/ = ca.pk1
   inner join course_main as cm2/*(error #2)*/ on ca.crsmain_pk1 = cm.pk1
   inner join course_users as cu on u.pk1 /*(error #3)*/ = cu.users_pk1
....
您还混合了连接样式-我建议使用实际连接,而不是编写来自用户的
,当然_main


我确信,当您使用别名重写查询时,会更容易发现错误

我建议您在表中始终使用别名,如下所示

select
   u.user_id,
   cm.course_name,
   cm.course_id
from users as u
   cross join course_main as cm
   inner join course_application as ca on u.pk1 /*(error #1)*/ = ca.pk1
   inner join course_main as cm2/*(error #2)*/ on ca.crsmain_pk1 = cm.pk1
   inner join course_users as cu on u.pk1 /*(error #3)*/ = cu.users_pk1
....
您还混合了连接样式-我建议使用实际连接,而不是编写来自用户的
,当然_main


我确信,当您使用别名重写查询时,会更容易发现错误

正如其他人所说,您的问题是因为混合联接类型。我想这对你有用

您还加入了两次
course\u main
,我认为您可以将其压缩为
course\u应用程序
表中的一个连接

SELECT 
     u.user_id
    ,cm.course_name
    ,cm.course_id
FROM users AS u
CROSS JOIN course_main AS cm
JOIN course_application AS ca
  ON u.pk1 = ca.pk1
 AND ca.crsmain_pk1 = cm.pk1
JOIN course_u AS cu
  ON u.pk1 = cu.u_pk1
 AND cm.pk1 = cu.crsmain_pk1
 AND cm.pk1 = cu.child_crsmain_pk1
WHERE cu.role = 'P'
  AND cm.course_id LIKE '%FA2013'
  AND ca.application = 'alrn-AtomicLearning_tool' 

  AND (( 
        ca.enable_ind  = 'Y'
     OR ca.visible_ind = 'N' 
    ) OR (
        ca.enable_ind  = 'N'
     OR ca.visible_ind = 'Y' 
    ))

我认为与其在
用户
课程应用程序
之间交叉连接(您真的希望数据库中的每个用户和应用程序组合都有一行吗?),您的问题是因为混合联接类型。我想这对你有用

您还加入了两次
course\u main
,我认为您可以将其压缩为
course\u应用程序
表中的一个连接

SELECT 
     u.user_id
    ,cm.course_name
    ,cm.course_id
FROM users AS u
CROSS JOIN course_main AS cm
JOIN course_application AS ca
  ON u.pk1 = ca.pk1
 AND ca.crsmain_pk1 = cm.pk1
JOIN course_u AS cu
  ON u.pk1 = cu.u_pk1
 AND cm.pk1 = cu.crsmain_pk1
 AND cm.pk1 = cu.child_crsmain_pk1
WHERE cu.role = 'P'
  AND cm.course_id LIKE '%FA2013'
  AND ca.application = 'alrn-AtomicLearning_tool' 

  AND (( 
        ca.enable_ind  = 'Y'
     OR ca.visible_ind = 'N' 
    ) OR (
        ca.enable_ind  = 'N'
     OR ca.visible_ind = 'Y' 
    ))

我认为与其在
用户
课程应用程序
之间交叉连接(您真的希望数据库中的每个用户和应用程序组合都有一行吗?),您可能需要引入一个常规的
内部连接
,并在某个键上连接。

根据给出的所有建议重新编写查询

use BBLEARN
SELECT u.user_id,
    cm.course_name,
    cm.course_id
FROM users as u
join course_users cu on u.pk1 = cu.users_pk1
join course_main cm on cu.crsmain_pk1=cm.pk1
join course_application ca on cm.pk1 = ca.crsmain_pk1

WHERE cu.role='P'
AND
((cm.course_id) LIKE '%FA2013' AND (ca.application) = 'alrn-AtomicLearning_tool')
AND (((ca.enable_ind) = 'Y' OR (ca.visible_ind) = 'N')
OR ((ca.enable_ind) = 'N' OR (ca.visible_ind) = 'Y'))

根据给出的所有建议重新编写查询

use BBLEARN
SELECT u.user_id,
    cm.course_name,
    cm.course_id
FROM users as u
join course_users cu on u.pk1 = cu.users_pk1
join course_main cm on cu.crsmain_pk1=cm.pk1
join course_application ca on cm.pk1 = ca.crsmain_pk1

WHERE cu.role='P'
AND
((cm.course_id) LIKE '%FA2013' AND (ca.application) = 'alrn-AtomicLearning_tool')
AND (((ca.enable_ind) = 'Y' OR (ca.visible_ind) = 'N')
OR ((ca.enable_ind) = 'N' OR (ca.visible_ind) = 'Y'))


您正在混合连接类型,这是导致问题的原因。坚持使用ANSI sql(内部联接等)并删除
,course\u main
。为什么要将一个隐式联接与所有正确的联接混合使用?请提供要从中提取的表的完整表名列表?从查询中可以看出,您试图从一个名为“users”的表中提取,但第一个错误意味着没有“users”表(或者它没有pk1字段)。我需要从users和course_main中提取。仅仅从用户中选择不会返回所有数据,对吗?我没有明确地做任何事情。我进入SQLServer2008ManagementStudio中的数据库,选择了我希望能够在中使用条件的表,并根据主键匹配从中选择数据。这是一个指向数据库模式页面的链接,它确实有一个users表,并且肯定有一个pk1键,该键通常在其他表中用作外键。请注意,5表联接只是一个怪物。您混合了联接类型,这导致了问题。坚持使用ANSI sql(内部联接等)并删除
,course\u main
。为什么要将一个隐式联接与所有正确的联接混合使用?请提供要从中提取的表的完整表名列表?从查询中可以看出,您试图从一个名为“users”的表中提取,但第一个错误意味着没有“users”表(或者它没有pk1字段)。我需要从users和course_main中提取。仅仅从用户中选择不会返回所有数据,对吗?我没有明确地做任何事情。我进入SQLServer2008ManagementStudio中的数据库,选择了我希望能够在中使用条件的表,并根据主键匹配从中选择数据。这是一个指向数据库架构中某个页面的链接,它确实有一个users表,并且肯定有一个pk1键,该键在其他表中经常用作外键。请注意,5表联接只不过是一个怪物。这里不存在别名问题。由于混合联接,使用别名的示例查询将无法工作。@bluefeet yes,我的错:)我一直在写ANSI样式的连接,从来没有尝试过混合两种样式,而且ANSI连接并不难看。@RomanPekar为了让它更干净,您可能需要使用CROSSJOIN@bluefeet他改变了答案。事实上,我也真的不喜欢所有大写字母的写作风格:)alia