Microsoft Access SQL 查询中的字符串连接问题

Posted

技术标签:

【中文标题】Microsoft Access SQL 查询中的字符串连接问题【英文标题】:Problem with string concatenation in Microsoft Access SQL query 【发布时间】:2019-08-02 16:22:24 【问题描述】:

我在 Access 2016 数据库中有一个表,其中包含多个位置的信息。每个位置都以三种格式之一存储:

(type 1) standard US address with house number 
(type 2) street intersection
(type 4) GPS coordinates only 
(type 3 is not used in this database).  

我正在尝试使用查询将各个字段值连接成单个字符串,以便我可以在报告的文本框中显示该字符串。类型 1 的格式是

[HouseNumber],[HouseNumberSuffix],[PrefixDirectional],[StreetName],[StreetType],[Qualifier],[City]

在下面的示例中,第 2 行看起来像“100 E UNION ST, SOMERSET”。

类型2的格式是

[PrefixDirectional],[StreetName],[StreetType],'/',[XPrefixDirectional],[XStreetName],[XStreetType] 

在下面的示例中,第 3 行应类似于“N CENTER AVE/E MAIN ST”。

类型3的格式是

[LatitudeY],"|",[LongitudeX]

在下面的示例中,第 6 行应类似于“39.957384|-78.824255”。

类型 1 和 2 由生成此数据的应用程序进行地理编码,因此它们还包括 Lat 和 Long 值(如果可用),但在连接这些行时不需要考虑这些字段。在此实现中,许多字段包含空值。由于 Microsoft Access 不支持 CONCAT_WS() SQL 函数,我一直在绞尽脑汁试图找到一种解决方法来连接字符串,同时消除空字段的额外空格。

这是我的表格示例:

Table: Dim_Address

|AddressID|LocationType|HouseNumber|HouseNumberSuffix|PrefixDirectional|StreetName      |StreetType|XPrefixDirectional|XStreetName|XStreetType|Qualifier|City      |LatitudeY   |LongitudeX   |
|---------|------------|-----------|-----------------|-----------------|----------------|----------|------------------|-----------|-----------|---------|----------|------------|-------------|
|1        |1           |           |                 |                 |<UNKNOWN>       |          |                  |           |           |         |          |            |             |
|12       |1           |100        |                 |E                |UNION           |ST        |                  |           |           |         |SOMERSET  |40.0092574  |-79.078380702|
|37       |2           |           |                 |N                |CENTER          |AVE       |E                 |MAIN       |ST         |         |SOMERSET  |40.008420389|-79.078610673|
|6363     |4           |           |                 |                 |                |          |                  |           |           |         |SOMERSET  |39.996243   |-79.034395   |
|9302     |2           |           |                 |                 |MARKLETON SCHOOL|RD        |                  |ROCKDALE   |RD         |         |ROCKWOOD  |39.908031106|-79.160141687|
|9725     |4           |           |                 |                 |                |          |                  |           |           |         |BERLIN    |39.957384   |-78.824255   |
|8282     |1           |222        |                 |                 |MAIN            |ST        |                  |           |           |APT 13   |MEYERSDALE|39.814387822|-79.026677269|
|55233    |1           |2110       |1/2              |                 |GRAHAM          |AVE       |                  |           |           |         |WINDBER   |40.230844268|-78.82551539 |

[AddressID][LocationType][HouseNumber] 是整数; [LatitudeY][LongitudeX] 是双打;其余字段都是字符串。

这是我试图在查询中使用的代码:

SELECT
Switch(
[LocationType]=1,((CStr([HouseNumber])+' ') & ([HouseNumberSuffix]+' ') & ([PrefixDirectional]+' ') & ([StreetName]+' ') & [StreetType] & (', '+[Qualifier]) & (', '+[VenueName])),
[LocationType]=2,(([PrefixDirectional]+' ') & ([StreetName]+' ') & ([StreetType]+' ') & ('/') & ([XPrefixDirectional]+' ') & ([XStreetName]+' ') & ([XStreetType]+' ')),
[LocationType]=4,(CStr([LatitudeY]) & ' | ' & CStr([LongitudeX]))
) AS LocationConcatenation
FROM Dim_Address;

以下是我在上表中运行查询时得到的结果:

|LocationConcatenation          |
|-------------------------------|
|#Error                         |
|100 E UNION ST, SOMERSET       |
|#Error                         |
|#Error                         |
|#Error                         |
|#Error                         |
|222 MAIN ST, APT 13, MEYERSDALE|
|2110 1/2 GRAHAM AVE, WINDBER   |

除了第 1 行之外,它对类型 1 的工作方式与预期完全相同。在此论坛的另一篇文章 (CONCAT equivalent in MS Access) 上,有人建议使用 + 进行连接会创建空字符串,如果用于连接一个字符串与另一个 null,所以我尝试了,但第 1 行仍然让我感到悲伤。对于类型 2 或 4,查询根本不起作用。谁能阐明我在哪里犯了错误?我对 SQL 相当熟悉,但对 Access 支持它的有限方式感到沮丧。 (顺便说一句,如果用户没有输入实际地址,则创建此数据的程序默认使用 作为地址的占位符,因此它出现在相关表的许多记录中)。

【问题讨论】:

为澄清起见,如果一个值存在于诸如[HouseNumber] 之类的字段中,那么我想将该值附加到结果字符串中,后跟一个空格以使其可读。如果值为 NULL,那么我不想在字符串中附加任何内容。所以,如果[HouseNumber] 是“100”,[HouseNumberSuffix] 是 NULL,[PrefixDirectional] 是“E”,[StreetName] 是“UNION”,我希望结果字符串是“100 E UNION”而不是“100EUNION”或“100 E UNION”(100 和 E 之间有两个空格)。 【参考方案1】:

您可以使用nz()ltrim() 和条件逻辑在 MS Access 中实现 concat_ws() 的等效项:

select Switch(LocationType = 1,
              ltrim(nz(" " + CStr(HouseNumber), "") +
                    nz(" " + HouseNumberSuffix, "") + 
                    nz(" " + PrefixDirectional, "") +
                    nz(" " + StreetName, "") +
                    nz(" " + StreetType, "") + ", " &
                    nz(" " + Qualifier, "") + ", "
                    nz(" " + VenueName, "")
                   ),
              . . .
              )

【讨论】:

在您的示例中,使用双引号而不是单引号作为字符串分隔符有区别吗?我搜索了几个站点以获取有关查询语法的参考,并找到了两者的示例。 @Skippy687 。 . .我将双引号与作为 MS Access 的标准相关联(与标准 SQL 和其他数据库相比)。如果一直使用,我认为您可以使用其中任何一种。 @GordonLinoff:Nz 在这里没用:Nz(" " &amp; HouseNumberSuffix, "")。您的意思是:Nz(" " + HouseNumberSuffix, "") @Gustav 。 .为什么nz() 没用?如果HouseNumberSuffixNULL,则表达式" " &amp; HouseNumberSuffix 应该返回NULL。然后nz() 返回一个空字符串。 @GordonLinoff:不是和符号;但是有了 plus 就可以了。

以上是关于Microsoft Access SQL 查询中的字符串连接问题的主要内容,如果未能解决你的问题,请参考以下文章

您如何计算 Microsoft Access SQL 查询中的连续日期?

odbc_exec():SQL 错误:[Microsoft][ODBC Microsoft Access Driver] 查询表达式中的语法错误(缺少运算符)

Microsoft Access/SQL 错误参数框

Microsoft Access SQL 查询计数不同

如何在 Microsoft Access 中通过 VBA 设置 INSERT SQL 查询的参数值?

Microsoft Access 数据库引擎 2016 - 在 2010 中正常工作的某些 SQL 查询出现问题