【问题标题】:Monster of an inner join...multi part ... could not be bound?内联怪物……多部分……无法绑定?
【发布时间】:2013-07-02 19:25:40
【问题描述】:

我有这个 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 表之前,我已经运行了查询。由于它们具有直接关系,因此只需一个连接即可实现这一目标。添加这 2 个额外的表(users 和 course_users 以定义哪些用户在我们的数据库中与其他表中的键匹配为特定角色)使其变得更加复杂。

这些是四个表的架构:

http://pastebin.com/AJuiGv9s

【问题讨论】:

  • 您正在混合导致问题的 JOIN 类型。坚持使用 ANSI sql(INNER JOIN 等)并删除 , course_main
  • 你为什么使用一个隐式连接和所有正确的连接?
  • 您能否提供您要从中提取的表的完整表名列表?从查询中可以看出,您正试图从一个名为“users”的表中提取,但第一个错误意味着没有“users”表(或者它没有 pk1 字段)。
  • 我需要从用户和 course_main 中提取。仅从用户中选择不会返回所有数据,对吗?我没有明确地做任何事情。我进入 Sql Server 2008 管理工作室中的数据库,并选择了我希望能够在其中使用条件并根据主键匹配从中选择数据的表。这是从数据库架构到页面的链接,它确实有一个用户表,并且肯定有一个 pk1 键,该键经常在其他表中用作外键library.blackboard.com/ref/8c156cbc-7160-4e64-9f00-f06ea67a0fe0/…
  • 请注意,5 表连接不过是个怪物。

标签: sql sql-server-2008 tsql


【解决方案1】:

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

您还两次加入了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 之间的交叉连接(您真的希望数据库中用户和应用程序的每个组合都有一行吗?),您可能想引入一个常规@ 987654328@ 并加入一些关键。

【讨论】:

  • 如果我链接到表的模式会更有帮助吗?该代码确实有效,但不返回任何结果。我写这篇文章是为了了解哪些用户正在教授哪些课程,我需要在上面的其他查询中更进一步,选择满足特定应用标准的课程、讲师和用户。 pastebin.com/YBGcdAbx
  • 他可能需要加入那张桌子两次。
  • @user1275954:您在 Pastebin 示例中加入 userscourse_maincourse_users 的方式对我来说更有意义。为什么不尝试围绕 3 表连接构建整个东西?
  • 我想我做了一个应该可以工作的四表连接。告诉我你的想法! pastebin.com/vSVVvyqK
  • @user1275954:看起来不错,但它是否会返回正确的结果,您可以更好地判断。但是,它不会像您的原始查询那样以任何方式使用 course_users.child_crsmain_pk1 列,这使得您的修订版本看起来与原始版本不同(意图)。
【解决方案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

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

【讨论】:

  • 别名不是这里的问题。
  • 由于混合的 JOIN,您的带有别名的示例查询将不起作用。
  • @bluefeet 是的,我的错 :) 我一直在编写 ANSI 样式连接,从未尝试混合两种样式,而且不是 ANSI 连接很丑。
  • @RomanPekar 为了让它更干净,您可能需要使用 CROSS JOIN
  • @bluefeet 更改了答案。实际上,我也真的不喜欢所有大写的写作风格:)
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2010-11-02
    • 2023-03-21
    相关资源
    最近更新 更多