内部联接的怪物......多部分...无法绑定?

时间:2013-07-02 19:25:41

标签: 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
       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' ) ) 

所有嵌套连接都让我很头疼。我希望SQL Server 2008与查询设计器能够至少输入别名,但我想我错了。

当我在编辑器中时,我在第一次加入users.pk1时收到错误

  

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

我也遇到了这个错误:

  

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

我隐约知道别名,并且知道如何将它们放入SQL中以执行非常非常基本的任务,但我只是将自己混淆到不归路。我已经阅读了关于别名的所有内容但只是不知道在这个复合体的连接中正确使用它们的位置。请帮忙!

谢谢

编辑:我不确定如何陈述我的意图。基本上我正试图从我选择的所有表中得到3列。获取正确的数据,以及表之间必须匹配的所有键。在SQL Server 2008中,我选择了所有具有关系的表。在我选择的所有内容之前,我运行了查询是course_main和course_application表。由于那些具有直接关系,因此只需要一次连接即可实现这一目标。添加这两个额外的表(用户和course_users来定义哪些用户在我们的数据库中与其他表中的键匹配作为特定角色)使得它变得更加复杂。

这些是四个表的模式:

http://pastebin.com/AJuiGv9s

3 个答案:

答案 0 :(得分:2)

我建议您始终为表格使用别名,例如

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
....

您还混合了连接样式 - 我建议使用实际连接而不是编写from users, course_main

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

答案 1 :(得分:2)

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

您也加入了course_main两次,我认为您可以将其浓缩为course_application表中的一个联接。

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' 
    ))

我在想,而不是userscourse_application之间的交叉连接(你真的想在数据库中为每个用户和应用程序组合添加一行吗?),你可能想要引入常规INNER JOIN并加入一些密钥。

答案 2 :(得分:0)

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

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'))

http://pastebin.com/vSVVvyqK