Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MSSQL-如果字段的数据类型不同,如何联接表?_Sql Server - Fatal编程技术网

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
。感谢您的解释和建议!