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)
您的查询使用的是 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_date
在WHERE
子句中的两个条件周围加上括号,因为它们都是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)