Sql 执行此选择查询的更快方法
假设Employee有三列 名字、姓氏和ID 查询应首先在firstname中搜索名称,仅当未找到该名称时搜索姓氏Sql 执行此选择查询的更快方法,sql,nhibernate,Sql,Nhibernate,假设Employee有三列 名字、姓氏和ID 查询应首先在firstname中搜索名称,仅当未找到该名称时搜索姓氏 因此,请从名为“test%”或名为“test%”的员工中选择*。他不会工作的 下面的查询将起作用 select FirstName, LastName, ID from EMPLOYEE WHERE LastName = 'Test%' AND (COUNT(SELECT FirstName, LastName, ID FROM EMPLOYEE WHER
因此,请从名为“test%”或名为“test%”的员工中选择*。他不会工作的 下面的查询将起作用
select FirstName, LastName, ID
from EMPLOYEE
WHERE
LastName = 'Test%'
AND
(COUNT(SELECT FirstName, LastName, ID FROM EMPLOYEE WHERE FirstName = 'Test%')=0)
OR
SELECT FirstName, LastName, ID FROM EMPLOYEE WHERE FirstName = 'Test%'
我需要把它映射回NHibernate,有没有一种更快更有效的方法来代替两次数据库调用
Select *
From Employee
Where FirstName Like @Text + '%'
Union
Select *
From Employee
Where LastName Like @Text + '%';
就算你不在乎他们回来的顺序。如果记录必须返回与名字匹配的记录,然后是与姓氏匹配的名称,那么这将不起作用
就算你不在乎他们回来的顺序。如果返回的记录必须是名字匹配的记录,然后是姓氏匹配的记录,那么这将不起作用。尝试一下:
SELECT FirstName, LastName, ID FROM EMPLOYEE WHERE FirstName = 'Test%'
OR (FirstName <> 'Test%' AND LastName = 'Test%')
从员工中选择FirstName、LastName、ID,其中FirstName='Test%'
或(FirstName'Test%'和LastName='Test%')
试试这个:
SELECT FirstName, LastName, ID FROM EMPLOYEE WHERE FirstName = 'Test%'
OR (FirstName <> 'Test%' AND LastName = 'Test%')
从员工中选择FirstName、LastName、ID,其中FirstName='Test%'
或(FirstName'Test%'和LastName='Test%')
“过早优化是万恶之源”
为什么您会关心优化器所看到的搜索是如何完成的,而不是声明您想要什么?
这一切归结为一个布尔真值表:当FirstName匹配时,需要记录(LastName、match或nomatch中的任何内容),如果FirstName不匹配,则需要LastName匹配时的记录:
F match, L match => yes
F match, L nomatch => yes
F nomatch, L match => yes
F nomatch, L nomatch => no
这正是OR条件:(名字匹配)或(姓氏匹配)
;只有FirstName和LastName不匹配时才会丢弃记录
布尔优化将确保当第一个条件为真时,第二个条件甚至不会被计算
所以你的问题是:
SELECT FirstName, LastName, ID
FROM Employee
WHERE (FirstName LIKE 'Test%')
OR (LastName LIKE 'Test%')
更新:如果确实不返回任何与姓氏匹配的记录(如果只找到姓氏的记录),我可能误解了目标…
无论如何,关于过早优化的立场仍然有效…
不知何故,您需要一个2遍的查询,因为在确定FirstName没有匹配项之前,您无法判断是否要考虑LastName。但是有了适当的索引和统计数据,优化器将使其非常高效
查询:
SELECT FirstName, LastName, ID
FROM Employee
WHERE (FirstName LIKE 'Test%')
OR (LastName LIKE 'Test%'
AND (SELECT Count(ID)
FROM Employee
WHERE FirstName LIKE 'Test%') = 0)
只比之前的价格稍微贵一点。“过早优化是万恶之源”
为什么您会关心优化器所看到的搜索是如何完成的,而不是声明您想要什么?
这一切归结为一个布尔真值表:当FirstName匹配时,需要记录(LastName、match或nomatch中的任何内容),如果FirstName不匹配,则需要LastName匹配时的记录:
F match, L match => yes
F match, L nomatch => yes
F nomatch, L match => yes
F nomatch, L nomatch => no
这正是OR条件:(名字匹配)或(姓氏匹配)
;只有FirstName和LastName不匹配时才会丢弃记录
布尔优化将确保当第一个条件为真时,第二个条件甚至不会被计算
所以你的问题是:
SELECT FirstName, LastName, ID
FROM Employee
WHERE (FirstName LIKE 'Test%')
OR (LastName LIKE 'Test%')
更新:如果确实不返回任何与姓氏匹配的记录(如果只找到姓氏的记录),我可能误解了目标…
无论如何,关于过早优化的立场仍然有效…
不知何故,您需要一个2遍的查询,因为在确定FirstName没有匹配项之前,您无法判断是否要考虑LastName。但是有了适当的索引和统计数据,优化器将使其非常高效
查询:
SELECT FirstName, LastName, ID
FROM Employee
WHERE (FirstName LIKE 'Test%')
OR (LastName LIKE 'Test%'
AND (SELECT Count(ID)
FROM Employee
WHERE FirstName LIKE 'Test%') = 0)
只比前一个稍微贵一点。我认为这些问题都不能回答这个问题。我的理解是,搜索“John%”时应返回姓氏为John、Johnson等的员工。只有当没有姓氏为John、Johnny等的员工时,才会返回。如果表中同时包含John Adams和Lyndon Johnson,则显示的所有查询都将返回John Adams和Lyndon Johnson,但只应显示John Adams,因为只有当没有匹配的名字时,姓氏才应该匹配
下面是一个使用SQL Server语法的建议。应该可以用SQL的其他方言来编写:
select top (1) with ties
FirstName, LastName, ID
from (
select
0 as SearchLastNames,
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
union all
select
1 as SearchLastNames,
FirstName, LastName, ID
from EMPLOYEE
where LastName like 'Test%'
) as T
order by SearchLastNames;
如果有任何匹配的名字,则最小的SearchLastNames值将为0,顶部(1)的值将为ties。。order by SearchLastNames将仅返回与名字匹配的信息(其中SearchLastNames为0)
如果没有匹配的名字,则唯一的SearchLastNames值将为1。在这种情况下,TOP将返回所有姓氏匹配的信息(其中SearchLastNames为1),如果有
一个更笨拙但更便携的解决方案是:
select
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
union all
select
FirstName, LastName, ID
from EMPLOYEE
where LastName like 'Test%'
and not exists (
select
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
);
我认为这些问题都不能回答这个问题。我的理解是,搜索“John%”时应返回姓氏为John、Johnson等的员工。只有当没有姓氏为John、Johnny等的员工时,才会返回。如果表中同时包含John Adams和Lyndon Johnson,则显示的所有查询都将返回John Adams和Lyndon Johnson,但只应显示John Adams,因为只有当没有匹配的名字时,姓氏才应该匹配
下面是一个使用SQL Server语法的建议。应该可以用SQL的其他方言来编写:
select top (1) with ties
FirstName, LastName, ID
from (
select
0 as SearchLastNames,
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
union all
select
1 as SearchLastNames,
FirstName, LastName, ID
from EMPLOYEE
where LastName like 'Test%'
) as T
order by SearchLastNames;
如果有任何匹配的名字,则最小的SearchLastNames值将为0,顶部(1)的值将为ties。。order by SearchLastNames将仅返回与名字匹配的信息(其中SearchLastNames为0)
如果没有匹配的名字,则唯一的SearchLastNames值将为1。在这种情况下,TOP将返回所有姓氏匹配的信息(其中SearchLastNames为1),如果有
一个更笨拙但更便携的解决方案是:
select
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
union all
select
FirstName, LastName, ID
from EMPLOYEE
where LastName like 'Test%'
and not exists (
select
FirstName, LastName, ID
from EMPLOYEE
where FirstName like 'Test%'
);
我真的不认为您需要担心编写两个数据库调用的开销