2014-03-31 88 views
1

如何編寫具有嵌套過濾器的SQL查詢。SQL:基於多個過濾器的多個Where子句

信息:2的搜索過濾器

1過濾器:ID,姓名,日期
第二過濾器:根據第一,對於編號:準確,範圍;對於名稱:確切的,像;爲日期:確切,範圍。

在LINQ代碼的做一樣的東西:

theList = somelistFromDb; 
case filter1 
    case "Id" 
     if filter2 == "exact" 
      theList.where(x => x == searchkey); 
     else if filter 2 == "range" 
      theList.where(x => x >= searchkey && x<=searchkey2); 
    case "Name" 
     if filter2 == "exact" 
      theList.where(x => x == searchkey); 
     else if filter2 == "like" 
      theList.where(x => x.contains("searchkey)); 
... 

如何轉換LINQ以上的僞代碼到SQL?

+0

@MarcGravell - 如果它們是兩個比較中涉及的相同值,我同意你的看法,但似乎涉及3個值('x','searchKey'和'searchKey2') –

+0

@Damien_The_Unbeliever I錯過了,ta –

+0

上述代碼中的「theList」變量是從存儲過程返回的。 SP將「全部返回」,並在C#中完成過濾和排序。任務是將上面的僞代碼合併到SP中,因此所有事情都在數據庫服務器上完成「優化」,並且返回的列表將被過濾和排序。順便說一句,謝謝你們... –

回答

1
SELECT 
... 
WHERE 
    (:filterParam='Id' AND <all the Id filter conditions> here) 
OR 
    (:filterParam='Name' AND <all the Name filter conditions> here) 
1
select * from [Table] where 
((@filter1='Id') and 
    ((filter2='exact' and [Table].[Id][email protected]) OR 
    (filter2='range' and [Table].[Id]>[email protected] and [Table].[Id]<[email protected]))) 
OR 
((@filter1='Name') and 
..... 
+0

我試圖實現它,但我有數據轉換錯誤。你有沒有在轉換數據的工作? –

+0

我不知道你使用了什麼數據,所以我不能給你一個建議 – MikkaRin

+0

在我的例子中searchKey可以是一個字符串,一個int或一個日期。如果filter2是範圍,那麼在'Id'搜索中,我必須將它們轉換爲int。但是如果filter1是'Name'並且我會傳入'Harry',它會拋出錯誤,因爲它無法轉換爲int。似乎一切都被評估不短路。 –

1

寫一個TSQL查詢滿足或排除所有一氣呵成的條件通常是非常不理想的 - 它會導致可怕的查詢計劃。試圖在TSQL中做所有的思考是......有點難看 - TSQL根本不是一個很好的語言。

所以我通常會做到這一點的方式是通過建立在C#中的查詢,例如:

static void AppendFilter(StringBuilder filter, string clause) 
{ 
    filter.Append(filter.Length == 0 ? " where " : " and ").Append(clause); 
} 

StringBuilder filter = new StringBuilder(); 
if(/* some condition */) 
    AppendFilter(filter, "row.Foo = @foo"); 
if(/* some condition */) 
    AppendFilter(filter, "row.Bar > @bar"); 
// ... 
string tsql = "select * from SomeTable row" + filter.ToString(); 
// pack params, exec 

此:

  • 擴展到任何數量的過濾器
  • 產生適當的每個過濾器組合的TSQL,用於優化查詢計劃
  • 易於維護

就個人而言,我也想用短小精悍做執行,作爲具有(鹼性)參數分析內置的,允許簡單:

var rows = conn.Query<SomeType>(tsql, new { foo, bar, ... }).ToList(); 

(但它仍然只發送必要的參數)

但是,另一種方法是在每個if中添加參數。