How do I write an SQL query that has nested filters.
Info: 2 search filters
1st filter: Id, Name, Date
2nd filter: depending on first, for Id: exact, range; for Name: exact, like; for Date: exact, range.
In LINQ code its was done something like:
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));
...
How do I convert the above LINQ Pseudocode to SQL?
SELECT
...
WHERE
(:filterParam='Id' AND <all the Id filter conditions> here)
OR
(:filterParam='Name' AND <all the Name filter conditions> here)
select * from [Table] where
((@filter1='Id') and
((filter2='exact' and [Table].[Id]=@searchkey) OR
(filter2='range' and [Table].[Id]>=@searchkey and [Table].[Id]<=@searchkey2) ))
OR
((@filter1='Name') and
.....
Writing a single TSQL query that satisfies or excludes all the conditions in one go is usually very suboptimal - it leads to terrible query plans. Trying to do all the thinking in TSQL is... somewhat ugly - TSQL simply isn't a great language for it.
So: the way I would usually do this is by building the query in C#, for example:
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
This:
Personally, I'd also use dapper to do the execution, as that has (basic) parameter analysis built in, allowing simple:
var rows = conn.Query<SomeType>(tsql, new { foo, bar, ... }).ToList();
(yet it will still send only the necessary parameters)
An alternative, though, is to add the parameters in each if
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.