Sql server MSSQL-如果字段的数据类型不同,如何联接表?
我正在合并几个表以显示结果Sql server MSSQL-如果字段的数据类型不同,如何联接表?,sql-server,Sql Server,我正在合并几个表以显示结果 SELECT a.*, b.type FROM [testing].[PICKDETAIL] a left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY left join [testing].[LOC] c on A.LOC = c.LOC left join [testing].[CODELKUP] d on c.ZCOORD = d.CODE WHERE a.S
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on c.ZCOORD = d.CODE
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
但是c.ZCOORD的数据类型是INT,d.CODE的数据是NVARCHAR。
有没有办法用这两个字段连接表?您可以尝试以下查询
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on c.ZCOORD = CAST(d.CODE AS INT)
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
如果确定
d.code
的所有值都将包含整数,则可以执行显式转换。如果是这种情况,请考虑将列数据类型更改为<代码> int >代码>,因为它将减小大小和提升性能。
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on c.ZCOORD = CONVERT(INT, d.CODE)
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
如果您不确定或者它可能包含非整数值,那么您的选择将是另一种方式,将c.ZCOORD
转换为nvarchar
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on CONVERT(NVARCHAR(20), c.ZCOORD) = d.CODE
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
这两种方法都不利于性能,因为您将函数(转换数据类型)应用于列,这将使这些列上可能存在的索引的使用无效
如果保持原样,SQL引擎很可能会将最复杂的类型转换为更简单的类型,在这种情况下,它将执行从
NVARCHAR
到INT
的隐式转换,因为比较INT要比nvarchars快得多。您可以尝试将d.code转换为INT数据类型。
使用
在c.ZCOORD=cast(d.CODE as int)上左键连接[testing].[CODELKUP]d在进一步查看该查询之后,我只需发布一个答案并解释其中的一些问题:
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on c.ZCOORD = d.CODE
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
好的,从哪里开始。首先,我最讨厌的事之一是你的化名。你的方式很混乱。“d”代表CODELKUP
,“c”代表LOC
?这有什么意义呢
接下来,您的左连接到订单
。您有一个WHERE
子句和b.[TYPE]='RT-b'
。这会隐式地将左连接
转换为内部连接
。这可能会影响性能
SELECT a.*, b.type
FROM [testing].[PICKDETAIL] a
left join [testing].[ORDERS] b on a.ORDERKEY = b.ORDERKEY
left join [testing].[LOC] c on A.LOC = c.LOC
left join [testing].[CODELKUP] d on c.ZCOORD = CONVERT(INT, d.CODE)
WHERE a.STATUS = 0
AND b.[TYPE] = 'RT-B'
此外,c
和d
(它们又是什么表格?)在
子句上的之后不再被引用。它们不在WHERE
或SELECT
中;那他们为什么在那里?他们似乎没有向查询添加任何内容
现在,关于你手头的问题,code
是一个nvarchar
,ZCOORD
是一个int
。如果您确实将其保持原样,则code
将根据进行隐式转换,因为int
。如果code
中有任何无法转换为int
的值,这将是一个问题;例如'1A01'
。这也意味着像'0101'
、'101'
和'00101'
这样的值将被视为相同的值(101
);这可能是也可能不是预期的行为
无论哪种方式,隐式转换都会使您的查询不可搜索,nvarchar
的顺序结构与int
非常不同。例如,对于一个nvarchar
,下面的表达式将为真:'9'>'8465537632'
。是的,没错,“数字”9的值比“数字”84亿的值高
正确的解决方案是修复您的数据类型,但是,我对您的数据了解不够,无法给出“正确”的答案;因此,我将采取更安全的选择,将ZCOORD
更改为nvarchar
,而不是code
更改为int
首先,添加新列:
ALTER TABLE testing.LOC ADD COLUMN ZCOORDn nvarchar(100); --I don't know the data size, so you'll need to change this.
接下来,您需要更新新列的值:
UPDATE testing.LOC
SET ZCOORDn = ZCOORD;
现在,我们可以删除旧列并添加新列:
ALTER TABLE testing.LOC DROP COLUMN ZCOORD;
GO
EXEC sp_rename N'testing.LOC.ZCOORDn',N'ZCOORD',N'COLUMN';
现在,您可以编写查询而不必考虑隐式转换:
SELECT PD.*, --* is probably a poor choice. Declare your columns
O.[TYPE] --Be consistance. This was [TYPE] in your WHERE, but it's type here.
FROM [testing].[PICKDETAIL] PD --Changed Alias
JOIN [testing].[ORDERS] O ON PD.ORDERKEY = O.ORDERKEY --Changed Alias, also now an INNER JOIN
LEFT JOIN [testing].[LOC] L ON PD.LOC = L.LOC --Changed Alias, is this needed though, it's not in the SELECT, so why is it here?
LEFT JOIN [testing].[CODELKUP] C on L.ZCOORD = C.CODE --Changed Alias, is this needed though, it's not in the SELECT, so why is it here?
WHERE PD.[STATUS] = 0
AND O.[TYPE] = 'RT-B';
注意我在上面的查询中输入的注释,有很多。使用CONVERT
或CAST
,但是,如果code
存储的是int
值,那么更好的答案是修复数据类型。在ON
子句中使用CONVERT
/CAST
的查询将是不可搜索的,这会影响性能。或者,如果code
存储的其他值不是int
,那么可能ZCOORD
应该存储为nvarchar
,或者您应该有一个持久化的计算列,其中包含TRY\u CONVERT
。感谢您的解释和建议!