2009-09-01 73 views
0

說員工有三列 名字,姓氏和ID。更快的方法來做到這一點選擇查詢

該查詢應首先搜索名字中的名字,僅當其未找到時搜索姓氏。

so select * from Employee where FirstName ='test%'或lastname ='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,有沒有更快的有效的方式來做到這一點,而不是做兩個數據庫調用?

+1

我真的不認爲你需要擔心寫兩個數據庫調用的開銷。 – Juliet 2009-09-01 19:57:11

+0

只要FirstName和LastName都是索引的,幾乎任何非愚蠢的查詢都會非常有效(除非您的數據庫擁有數百萬條記錄)。 – Brian 2009-09-01 19:57:16

+0

「so select * from Employee where FirstName ='test%'or Lastname ='test'%'。wont'work。」 如果您在FirstName匹配時始終需要記錄(不管LastName是什麼),那麼這確實是查詢。詳情請參閱我的回答。 – 2009-09-02 01:07:02

回答

1

給這一個嘗試:

SELECT FirstName, LastName, ID FROM EMPLOYEE WHERE FirstName = 'Test%' 
OR (FirstName <> 'Test%' AND LastName = 'Test%') 
+1

名字<>'測試%'是不必要的。做真相表... – 2009-09-02 01:01:49

0
Select * 
From Employee 
Where FirstName Like @Text + '%' 

Union 

Select * 
From Employee 
Where LastName Like @Text + '%'; 
+0

人們會解釋他們爲什麼拒絕投票嗎? – ChaosPandion 2009-09-01 19:55:38

+0

我沒有downvote,但我不認爲這回答了這個問題。 「查詢應該首先搜索名字中的名字,但前提是找不到名字搜索。」 – 2009-09-01 19:58:07

+0

這將用於沒有程序的目的。 – ChaosPandion 2009-09-01 19:59:04

1
FROM Employee 
WHERE (FirstName LIKE 'Test%' AND LastName NOT LIKE 'Test%') 
OR (LastName LIKE 'Test%' AND firstName NOT LIKE 'Test%') 

就算你不在乎他們來什麼樣的順序回。如果記錄必須與第一名稱匹配的記錄回來,其次是名稱,其中姓氏匹配,那麼這將無法工作。

+0

在4000個條目的數據集上,最終速度是前者的兩倍,儘管您可能已經知道這一點。 – ChaosPandion 2009-09-01 20:13:41

+0

這是專門針對SQL Server的。 – ChaosPandion 2009-09-01 20:14:16

+0

此查詢在HQL中。我已經做了幾乎這完全在我的系統上,授予它是Hibernate,而不是NHibernate,它工作 – Zoidberg 2009-09-01 20:45:16

1

「過早的優化是所有罪惡的根源。」

爲什麼要關注如何在優化器看到它時完成搜索,而不是聲明你想要的?
這一切都歸結爲一個布爾真值表:名字相匹配的時候,你想記錄(無論是名字,比賽或NOMATCH),如果名字不匹配,你想要的記錄時,名字相匹配:

F match, L match => yes 
F match, L nomatch => yes 
F nomatch, L match => yes 
F nomatch, L nomatch => no 

這正是OR條件:(FirstName matching) OR (LastName matching);唯一的丟棄記錄是當名字和姓氏不匹配時。

布爾優化將確保當第一個條件爲真時,第二個條件甚至不會被評估。

所以您查詢的是:

SELECT FirstName, LastName, ID 
FROM Employee 
WHERE (FirstName LIKE 'Test%') 
    OR (LastName LIKE 'Test%') 

更新:我可能誤解了目標,如果它確實不返回任何名字匹配如果記錄被發現只用名字...
不管怎麼說,過早優化的立場仍然有效...
你需要某種方式2傳遞查詢,因爲你不能分辨是否要考慮姓氏,直到你確定你沒有在名字上的任何匹配。但是,通過適當的索引和統計數據,優化器將使其非常高效。

查詢:

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) 

只是比以前稍微貴一些。

0

我不認爲這些查詢都可以回答這個問題。我的理解是,如果沒有僱員名字叫約翰,約翰尼等,那麼對'約翰%'的搜索應該返回名字爲約翰,約翰遜等的僱員。所有查詢顯示將返回約翰亞當斯和林登約翰遜如果表包含兩個,但只有約翰亞當斯應該出現,因爲姓氏應匹配只有當沒有匹配的名字。

這是一個使用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,和TOP(1)有關係..爲了通過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%' 
); 
相關問題