【发布时间】:2016-02-27 14:23:07
【问题描述】:
我们开始维护一个使用 SQL Server 的新项目,但对于某些表中的数据存在一些问题,如下所述。有 2 个表名为 Employee 和 Pass,Pass 表保存每个 Employee 的进出。
员工
|| 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);
这部分给出了错误:“表'Pass'中的列'cardno8'是一种无效的类型,不能用作索引中的键列。”
create index idx_tEvent_cardno8 ON Pass(cardno8);
create index idx_tEmployee_cardno8 ON Employee (cardno8);
有什么想法吗?
【问题讨论】:
-
"我们已尝试创建索引,但无法为 CardNo 字段创建索引。"为什么不?你收到错误了吗?我看不出你不能创建这样一个索引的明显原因。
-
“我必须修剪卡号,因为数字大小不同” -
pass.cardno不等于对应的employee.cardno?你能举个例子吗? -
Unfortunatela 卡号保存 11 位给员工,而保存 10 位到 Pass 表前导零。出于这个原因,我不得不取卡号的最后 8 位数字。
-
您可能必须将
cast()right()函数转换为适当的类型。 -
你的意思是我只是在查询中强制转换 CardNo 字段而不将其数据类型从 varchar 更改为 int?另一方面,我应该创建您之前建议的索引吗?谢谢。
标签: sql sql-server join indexing common-table-expression