2016-02-27 52 views
1

我们开始维护一个使用SQL Server的新项目,并且在某些表中存在一些与数据有关的问题,如下所述。有两个表格EmployeePassPass表格保留每个Employee的进出。当FK字段为NULL时,使用索引来连接两个表

员工

|| ID  || Name  || CardNo || 
====================================== 
|| 1  || John  || 101 || 
|| 2  || Christof || 102 || 
|| 3  || Jurgen  || 103 || 
|| 4  || Jose  || 104 || 
|| 5  || Mary  || 105 || 

|| ID  || EmployeeID || CardNo || 
====================================== 
|| 1  || NULL  || 101 || 
|| 2  || NULL  || 105 || 
|| 3  || NULL  || 103 || 
|| 4  || NULL  || 101 || 
|| 5  || NULL  || 102 || 
|| 6  || NULL  || 104 || 
|| 7  || NULL  || 104 || 
|| 8  || NULL  || 103 || 
|| 9  || NULL  || 105 || 
|| 10  || NULL  || 101 || 

在另一方面,作为Pass表的EmployeeID栏是空的每一个传球,我们必须使用CardNo列为了加入两张表。

但是,如下所示使用JOIN子句会导致查询执行更多时间,我认为可能有更好的方法,使用索引等代替PK来优化查询。我们已尝试创建索引,但无法创建CardNo列。

请您澄清我们如何解决问题?谢谢...

SELECT * 
FROM Pass p 
LEFT JOIN Employee e ON RIGHT(e.CardNo, 8) = RIGHT(p.CardNo, 8) --I have to trim card no as the digit sizes are different 

更新: 我试着应用以下脚本,但只有这部分工作:

alter table Pass add cardno8 as RIGHT(CardNo, 8); 
alter table Employee add cardno8 as RIGHT(CardNo, 8); 

这部分给出了错误:“列cardno8“表“通行证”的类型对于用作索引中的关键列无效。“

create index idx_tEvent_cardno8 ON Pass(cardno8); 
create index idx_tEmployee_cardno8 ON Employee (cardno8); 

任何想法?

+2

“我们试图创建索引,但不能创建CardNo场”为什么不?你有错误吗?我看不出有什么明显的理由,你不能创建这样的索引。 –

+0

“我没有修剪卡作为数字大小不同” - 'pass.cardno'不等于对应的'employee.cardno'?你能举个例子吗? –

+0

Unfortunatela卡号码被保存到员工11位数字,同时保存10位数字以传递表格前导零。出于这个原因,我不得不采取卡号的最后8位数字。 – hexadecimal

回答

1

如果问题是查询的表现,那么你只需要在Employee(CardNo)索引:

create index idx_employee_cardno on employee(cardno); 

如果你有兴趣只有一个或两个其他列(如姓名或ID),你可以在cardno之后将它们添加到索引中。

,我能想到的(除了权限)的唯一原因来解释为什么索引创建将失败是cardno有错误的类型。引述documentation

Columns that are of the large object (LOB) data types ntext , text , varchar(max) , nvarchar(max) , varbinary(max) , xml , or image cannot be specified as key columns for an index.

,这似乎不太可能,因为样本数据。如果这是一个问题,然后将类型更改为更合适的东西(或使用计算列,为了同样的目的)。

此外,您的查询应该在任何地方使用合格的列名(否则你会得到一个错误):

SELECT * 
FROM Pass p LEFT JOIN 
    Employee e 
    ON e.CardNo = p.CardNo; 
--------^ 
+0

非常感谢您的帮助。其实这个问题是相关的[通过多个分组加入多个表](http://stackoverflow.com/questions/35668526/join-multiple-tables-by-multiple-grouping/35668881?noredirect=1#comment59019450_35668881),我只是由于问题不同,cretae单独购票。所以,我就这个问题投了你的答案,但不幸的是无法创建索引。另一方面,你在那个问题上看到还有另一个问题让我强迫使用RIGHT函数。 – hexadecimal

+0

我上面更新了我的问题,能否请我一步一步阐明我应该遵循哪些程序来解决此问题?谢谢... – hexadecimal

+0

你说得对,问题实际上是CardNo字段(Varchar)的数据类型。所以,这意味着如果它是int,我们可以创建索引并用作FK,**是真的吗?** – hexadecimal

相关问题