【问题标题】:Prefix in field name SQL字段名称 SQL 中的前缀
【发布时间】:2015-12-27 10:27:41
【问题描述】:

在 SQL 方面,我是一个极端的菜鸟,我正在努力自学。我有几个关于 SQL 和编写查询的问题:

  1. 一位同事向我提供了一些查询示例,其中许多示例的字段名称都以 m 开头。或吨。或 o.email(例如 m.email 或 t.email 或 o.email)。前缀表示什么?

  2. 我正在尝试编写 JOIN 查询,但一直收到一条错误消息:在预期条件的上下文中指定的非布尔类型表达式,靠近 ')'什么会导致这种情况?我尝试加入的两个数据扩展都不包含 boonlean 字段。

我把它写成:

SELECT DISTINCT email, status_type, status_value_text FROM ent.[Table 1] JOIN [Table 2] ON email

再次重申,我非常新,任何帮助将不胜感激!

【问题讨论】:

  • 您的问题的答案不会真正改变,但[Table 1] 上的[] 语法表明您使用的不是MySQL,而是Microsoft 数据库,如Access 或SQL Server。 (除非您将它们包括为占位符)。你能用你真正使用的数据库标记你的问题吗?
  • 对不起!谢谢你的评论。 SQL Server 是正确的数据库。

标签: sql-server


【解决方案1】:

前缀表示什么?

如果您查看您所质疑的示例查询的FROM 子句,您应该注意到在完整表名之后指定的表别名。有时使用别名只是为了缩短需要完整拼写的表名,但大多数情况下需要使用别名来消除FROM 中多个表中类似名称的列之间的歧义。

SELECT
  -- Get the email column from the table aliased
  -- as `m` (table1)
  m.email
FROM
  -- table1 aliased as m
  table1 AS m
  -- table1 aliased as e
  INNER JOIN table2 AS e ON....

考虑两个相关的表,table1table2。他们都有一个名为email 的列。在SELECT 列表中,您不能只指定email,因为RDBMS 不会知道您想要哪一个。相反,您必须使用表名对其进行限定。由于表在FROM 中的别名为m, e,因此您必须使用SELECT 中的别名而不是完整的表名。

MS SQL Server documentation on table aliases...

在预期条件的上下文中指定的非布尔类型表达式,靠近 ')'

在您的联接的ON 子句中,您只需提供列名email,我们可以假设它是与两个表相关的公共值。连接的 ON 子句需要一个布尔表达式,其中 true 值在表之间进行逐行比较会返回一行。

所以ON 子句需要一个带有两侧的布尔表达式,或者返回 TRUE 的东西。在您的情况下,email 列之间是相等的

SELECT DISTINCT
   -- Must qualify email since both tables have it
   -- Using the full table name, or its alias if an alias
   -- was provided in `FROM`.
   [Table 1].email,
   status_type,
   status_value_text
FROM 
  ent.[Table 1]
  -- Equality between email columns completes the join
  JOIN [Table 2] ON [Table 1].email = [Table 2].email

ON 中的表达式可以是 anything,其计算结果为 TRUE。它不必是列值之间的精确匹配,尽管精确匹配是迄今为止最常见的用例。例如,您可以说ON 1 = 1,这是始终正确的。结果行集将匹配从[Table 1] 的每一行到[Table 2] 的每一行(这是一个笛卡尔积)。它也可能是ON 1 = 2,这是从不正确的,因此基本上没有意义,因为它永远不会返回行。

使用类似于您尝试的ON email 的语法,一些RDBMS 系统支持USING() 代替ON,允许您指定相等列而不是布尔表达式。因此,您也可以将其表达为

FROM 
  ent.[Table 1]
  JOIN [Table 2] USING (email)

另见What's the difference between ON and USING

【讨论】:

  • 您好,谢谢您的来信。我尝试编写 SELECT DISTINCT email AS Email, status_type AS BabyDobOrDue, status_value_text FROM ent.[table 1] a JOIN ent.[table 2] b ON a.email = b.email 但我收到的错误是“Query field.Ambiguous column命名为‘电子邮件’。”你知道那会是什么情况吗?
  • @psimp 这是由于缺少别名,假设两个表都有一个email 列。在我的顶级示例中,您将需要它的别名 SELECT DISTINCT a.email AS Email....(或 b.email,如果合适,但在这种情况下它应该无关紧要)。
【解决方案2】:
  1. 米。或吨。是查询中表的别名(因此您可能正在使用以字母 m 和 t 开头的表)。别名在查询的 FROM 部分中的表名之后指定。
  2. 语法不适合您的 JOIN。查询应该看起来更像这样:

选择 DISTINCT t1.email、t1.status_type、t2.status_value_text
从 [表 1] t1 JOIN [表 2] t2 ON t1.email = t2.email

查看此链接以查看更多示例。http://www.w3schools.com/sql/sql_join.asp

【讨论】:

    【解决方案3】:

    SQLSELECT 查询的一般形式是:

    SELECT (columns, expressions, aggregate functions)
    FROM (data sources)
    WHERE (filters on data sources)
    GROUP BY (columns used to group the data, needed if you use aggregate functions)
    HAVING (filters on data AFTER it's grouped)
    

    关于FROM 子句,如果您使用多个数据源(表或视图),您应该考虑您的数据将如何关联:

    1. 交叉连接返回所涉及表的笛卡尔积。

      示例:

      FROM foo, bar 将返回表foo 的所有行和表bar 的所有行,没有任何关于它们如何关联的规则。

    2. 内连接仅返回满足关系规则的数据。

      示例:

      FROM foo INNER JOIN bar ON foo.aField = bar.aField(替代:FROM foo JOIN bar ON foo.aField = b.aField)将仅返回满足所提供条件的foobar 行(每个表中的字段aField 必须匹配)。 重要提示: INNER JOIN 必须有一个布尔表达式,即关系必须为真或假;大多数情况下,这将是一个相等关系(=),但它可以是任何返回 TRUE/FALSE 值的东西(><>= 等)。

    3. 外连接返回一个表的完整数据,只返回另一个表中匹配关系规则的行(对于第一个表的任何其他不匹配行,第二个表中的列将有一个@987654338 @ 价值)。

      有两种可能的外连接:LEFT JOIN 将返回关系规则左侧表中的所有行,并且只返回关系右表的匹配行。 RIGHT JOIN 正好相反。

      示例:

      FROM foo LEFT JOIN bar ON foo.aField = bar.aField

      就像INNER JOIN 的情况一样,关系必须有一个布尔表达式。

    现在,正如您所注意到的,您需要告诉系统您从哪个字段获取数据。这就是“前缀”的原因:它们是表(或 schema.database.table)名称。如果你愿意,你可以在这个表名上使用 aliases (就像你可以在字段上使用别名一样):

    示例:FROM foo AS f INNER JOIN bar AS b on f.aField = b.aField

    每次在同一 SELECT 查询中使用字段时,都必须使用 FROM 子句中使用的别名。

    现在,明确谈论您的查询:您帖子中的JOIN 缺少关系规则:您告诉数据库服务器表是相关的,但您没有定义关系规则。哪些字段必须匹配?用表之间必须匹配的列完成JOIN 表达式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 2011-12-03
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      相关资源
      最近更新 更多