这个运算符是什么意思:*=

Mic*_*son 5 join ms-access sql-server

我有一个非常古老的 Access 应用程序,它使用 SQL Pass-Through 查询。此应用程序经过多次服务器升级,我们最近升级到 SQL 2012。

我现在收到一个语法错误。代码的最后两行就是问题所在。我相信这是某种 JOIN,但我从未见过这种语法。删除“*”允许查询运行,但会遗漏数据。是否可以轻松替换此语法,或者我是否需要使用 JOIN 短语重新设计这些查询?

SELECT survey.hole,survey_date,pit,cu,rec,zn, mn,north,east,elevation,
       rtrim(min_type) min_type,rtrim(rock_type) rock_type,
       rtrim(alt_type) alt_type, rtrim(min_style) min_style
FROM survey,assay,geology 
WHERE  mined_out IS NULL
AND pit = (SELECT fmpit FROM tyrctl WHERE source = 'export by date')
AND  (survey_date >= (SELECT fmdate FROM tyrctl WHERE source = 'export by date') 
AND survey_date <= (SELECT todate FROM tyrctl WHERE source = 'export by date')) 
AND survey.hole *= assay.hole
AND survey.hole *= geology.hole
Run Code Online (Sandbox Code Playgroud)

Sol*_*zky 6

您的查询使用的是 ANSI 之前的(也可能是原始的) JOIN 语法。回到“当天”,连接表是通过在FROM子句中指定所有表(用逗号分隔),然后在子句中指定连接条件来完成的WHERE。将当前的 ANSI 样式与旧样式等同起来可以为您提供以下选项图表:

  • [内部联接: TableA.Field = TableB.Field
  • 左 [外] 加入: TableA.Field *= TableB.Field
  • 右 [外部] 加入: TableA.Field =* TableB.Field
  • 完全[外部]加入: TableA.Field *=* TableB.Field
  • 交叉连接: {nothing specified to relate the two tables}

各种 RDBMS支持 / 之前的 ANSI 语法(有时会略有不同)。但是,它在 Microsoft SQL Server 中已被弃用一段时间,并在 SQL Server 2012 中被正式删除(如您现在所见)。这在 SQL Server 2012 MSDN 页面中的Discontinued Database Engine Functionality 中有所说明(网格中的倒数第二行)。

在您的查询中,您有 3 个表:

FROM survey,assay,geology
Run Code Online (Sandbox Code Playgroud)

和两个 LEFT JOIN 条件:

AND survey.hole *= assay.hole
AND survey.hole *= geology.hole
Run Code Online (Sandbox Code Playgroud)

但是,是的,您可以按如下方式重写它:

SELECT sy.hole, survey_date, pit, cu, rec, zn, mn, north, east, elevation,
       rtrim(min_type) AS [min_type], rtrim(rock_type) AS [rock_type],
       rtrim(alt_type) AS [alt_type], rtrim(min_style) AS [min_style]
FROM survey sy
LEFT JOIN assay ay
       ON ay.hole = sy.hole
LEFT JOIN geology gy
       ON gy.hole = sy.hole
WHERE  mined_out IS NULL
AND pit = (SELECT fmpit FROM tyrctl WHERE source = 'export by date')
AND (
      survey_date >= (SELECT fmdate FROM tyrctl WHERE source = 'export by date')
  AND survey_date <= (SELECT todate FROM tyrctl WHERE source = 'export by date')
    )
Run Code Online (Sandbox Code Playgroud)

从技术上讲,您不需要survey_dateWHERE子句中的两个条件周围加上括号,因为它们都是AND条件,但是如果您更喜欢它的可读性,那么它很好。


正如@ypercube 在对此答案的评论中指出的那样,查询可以进一步简化为,因为WHERE子句中的 3 个子查询都引用了同一个表的同一行。所以可以看看以下内容:

SELECT sy.hole, survey_date, pit, cu, rec, zn, mn, north, east, elevation,
       rtrim(min_type) AS [min_type], rtrim(rock_type) AS [rock_type],
       rtrim(alt_type) AS [alt_type], rtrim(min_style) AS [min_style]
FROM survey sy
INNER JOIN tyrctl tl
        ON sy.survey_date >= tl.fmdate
       AND sy.survey_date <= tl.todate
       AND sy.pit = tl.fmpit
       AND tl.source = 'export by date'
LEFT JOIN assay ay
       ON ay.hole = sy.hole
LEFT JOIN geology gy
       ON gy.hole = sy.hole
WHERE  mined_out IS NULL;
Run Code Online (Sandbox Code Playgroud)

  • 真的有 `*=*` 运算符吗?我以为只有 `*=` 和 `=*` 存在。 (2认同)
  • 当我在 SQL Server 2008 R2 中尝试使用 `*=*` 进行查询时,它给了我一个 `Incorrect syntax near '*'` 错误。(与其他两个一起工作正常。)当然,我在具有匹配兼容性级别 (80) 的数据库中尝试了它。 (2认同)
  • 这 3 个子查询具有相同的条件,因此它们可以由单个相关的条件替换:`AND EXISTS (SELECT * FROM tyrctl WHERE source = 'export by date' AND x.pit = fmpit AND y.survey_date &gt;= fmdate AND y.survey_date &lt;= todate)` - 其中 `x` 和 `y` 是正确的别名(`sy`、`ay` 或 `gy`) (2认同)
  • @ypercube 关于 `*=*` 语法,我可能记错了。我最初是在 96 年中期在 DB2/MVS 上学习这些东西的。在此和特定于供应商的变化之间,也许它从未在 SQL Server 中出现过。也许它永远不会出现在任何地方,而我是在做梦;-)。我暂时把它划掉。并呼吁减少“AND”条件。这也可以是一个简单的 INNER JOIN,因为它只匹配 `tyrctl` 中的一行。此外,我假设这些字段位于主“调查”表(“sy”)中,否则返回的行不会减少。 (2认同)