SQL:将一个表中的2列合并,以与另一个表中的1列进行比较

SQL:将一个表中的2列合并,以与另一个表中的1列进行比较,sql,sql-server,Sql,Sql Server,我在MSSQL中有两个表,一个叫做[DATA],另一个叫做[2020] 在[2020]中,我有用户信息,例如:姓名、ID、地址等。 在[DATA]中,我需要显示有关用户的多个列 问题是这些表之间没有公共列,在[2020]中我有ID和address,在[DATA]中,我在一个名为ID-address的列中有这些信息 所以我试过这个 SELECT A.ID, A.Nro, A.name, A.adress, B.CGE AS 'GE', B.CGG a

我在MSSQL中有两个表,一个叫做[DATA],另一个叫做[2020]

在[2020]中,我有用户信息,例如:姓名、ID、地址等。 在[DATA]中,我需要显示有关用户的多个列

问题是这些表之间没有公共列,在[2020]中我有ID和address,在[DATA]中,我在一个名为ID-address的列中有这些信息

所以我试过这个

SELECT
    A.ID,
    A.Nro,
    A.name,
    A.adress,
    B.CGE AS 'GE',
    B.CGG as 'GG',
    B.CPE AS 'PE'

FROM 
    [202009] A
    LEFT JOIN [DATA] B ON str(A.ID )+'-'+cast(A.adress as varchar) = B.[ID-adress]

但是我想在B上显示的列上得到NULL?我做错了什么?

我认为,您的直接问题是字符串函数
str(A.ID)+'-'+cast(A.address as varchar)
有几个问题

我建议将该SQL片段放入SELECT中,以查看您得到了什么(例如

看看你得到了什么结果

我相信

  • ID是数字的(可能是int)。str(A.ID)通常会在前面加上前导空格,在比较字符串时,
    '5'
    不同于
    '5'
    。在它前面放一个LTRIM,例如,
    LTRIM(str(A.ID))
  • cast(A.address作为varchar)
    需要varchar的长度,例如cast(A.address作为varchar(100))。若不这样做,则假定长度为1
要进行检查,请运行与上述类似的语句,但需要进行修复

SELECT A.ID, A.adress, ltrim(str(A.ID))+'-'+cast(A.adress as varchar(100)) 
FROM [202009] A
然而(我不想这么说),但这种设计……有问题。例如,当用户更改地址时会发生什么?数据表中的所有字段都将不可用

buck fix(imo)最大的好处是在数据表中为
ID
address
设置两个单独的字段。如果需要,您仍然可以保留单个字段(ID address)

正如您所说,确保它们具有公共列

一旦有了这两个字段,就可以在至少匹配的字段上连接它们,以获取该地址的相关数据行,例如

SELECT
    A.ID,
    A.Nro,
    A.name,
    A.adress,
    B.CGE AS 'GE',
    B.CGG as 'GG',
    B.CPE AS 'PE'

FROM 
    [202009] A
    LEFT JOIN [DATA] B ON A.ID = B.ID AND A.adress = B.adress
然后,如果您只需要一个给定用户的所有数据行,那么您可以做同样的事情,但不在地址上加入(只是a.ID=B.ID)


请注意,这并不能解决所有问题(例如,当一个表中的地址因空格或“St”vs“Street”等原因与另一个表中的地址不同时),但将是一个良好的开端。

我认为,您的直接问题是字符串函数
str(a.ID)+'-'+cast(a.address as varchar)
存在几个问题

我建议将该SQL片段放入SELECT中,以查看您得到了什么(例如

看看你得到了什么结果

我相信

  • ID是数字的(可能是int)。str(A.ID)通常会在前面加上前导空格,在比较字符串时,
    '5'
    不同于
    '5'
    。在它前面放一个LTRIM,例如,
    LTRIM(str(A.ID))
  • cast(A.address作为varchar)
    需要varchar的长度,例如cast(A.address作为varchar(100))。若不这样做,则假定长度为1
要进行检查,请运行与上述类似的语句,但需要进行修复

SELECT A.ID, A.adress, ltrim(str(A.ID))+'-'+cast(A.adress as varchar(100)) 
FROM [202009] A
然而(我不想这么说),但这种设计……有问题。例如,当用户更改地址时会发生什么?数据表中的所有字段都将不可用

buck fix(imo)最大的好处是在数据表中为
ID
address
设置两个单独的字段。如果需要,您仍然可以保留单个字段(ID address)

正如您所说,确保它们具有公共列

一旦有了这两个字段,就可以在至少匹配的字段上连接它们,以获取该地址的相关数据行,例如

SELECT
    A.ID,
    A.Nro,
    A.name,
    A.adress,
    B.CGE AS 'GE',
    B.CGG as 'GG',
    B.CPE AS 'PE'

FROM 
    [202009] A
    LEFT JOIN [DATA] B ON A.ID = B.ID AND A.adress = B.adress
然后,如果您只需要一个给定用户的所有数据行,那么您可以做同样的事情,但不在地址上加入(只是a.ID=B.ID)


请注意,这并不能解决所有问题(例如,当一个表中的地址因空格或“St”vs“Street”等原因与另一个表中的地址不同时),但将是一个良好的开端。

这里有一个调试建议:添加表达式(
str(a.ID)+'-'+cast(a.address as varchar)
)在选择中查看结果是否符合预期。

这里有一个调试建议:添加表达式(
str(a.ID)+'-'+cast(a.address as varchar)
)在您的SELECT中,查看结果是否符合您的预期。

从您相当稀疏的描述中,我想,
JOIN
条件的计算结果永远不会为true

根据列的命名,您可能需要:

FROM [202009] A LEFT JOIN
     [DATA] B
     ON CONCAT(A.ID, '-', A.adress) = B.[ID-adress]
这是基于对问题的合理解释的推测

您的构造存在两个潜在问题:

  • str()
    倾向于用空格填充值
  • varchar
    没有长度的默认长度取决于上下文,这可能不足以满足您的需要

  • 从你相当稀疏的描述中,我猜
    JOIN
    条件的计算结果永远不会为真

    根据列的命名,您可能需要:

    FROM [202009] A LEFT JOIN
         [DATA] B
         ON CONCAT(A.ID, '-', A.adress) = B.[ID-adress]
    
    这是基于对问题的合理解释的推测

    您的构造存在两个潜在问题:

  • str()
    倾向于用空格填充值
  • varchar
    没有长度的默认长度取决于上下文,这可能不足以满足您的需要

  • 请提供示例数据和所需结果。您可以尝试
    cast(A.ID为varchar(20))
    而不是
    str()
    @shawnt00 coment就是答案!非常感谢。把它写下来,这样我就可以投票并选择正确的答案。我可能是第一个提出这个建议的人。但是你可以随意接受另一个答案。我没有理由添加到列表中。很高兴它成功了。@Gordon和我的答案在将a.ID转换为字符串方面都是等效的。一切都会成功的我相信也会这样。我的是第一个,而Gordon的是最干净/最清晰的。请提供示例数据和所需结果。您可以尝试
    cas