希望通过SQL / TSQL获得与LINQ查询相同的输出

时间:2012-08-04 17:52:03

标签: sql sql-server linq tsql

使用LINQ我正在查询数据以进行排序,我得到了正确答案。

这是我的数据& linq查询......请看看。

void Main()
{
List<SearchResult> list = new List<SearchResult>() {
    new SearchResult(){ID=1,Title="Geo Prism GEO 1995 GEO* - ABS #16213899"},
    new SearchResult(){ID=2,Title="Excavator JCB - ECU P/N: 728/35700"},
    new SearchResult(){ID=3,Title="Geo Prism GEO 1995 - ABS #16213899"},
    new SearchResult(){ID=4,Title="JCB Excavator JCB- ECU P/N: 728/35700"},
    new SearchResult(){ID=5,Title="Geo Prism GEO,GEO 1995 - ABS #16213899 GEO"},
    new SearchResult(){ID=6,Title="dog"},
};

var to_search = new[] { "Geo", "JCB" }.Select(x => x.ToLower()).ToArray();

var result = from searchResult in list
let title = searchResult.Title.ToLower()
let key_string = to_search.FirstOrDefault(ts =>  title.Contains(ts))
orderby key_string == null ? -1 :  title.Split(new[]  { key_string },  StringSplitOptions.None).Length descending 
group searchResult by key_string into Group
    orderby Group.Count() descending
select Group;

result.Dump();

}

public class SearchResult
{
public int ID { get; set; }
public string Title { get; set; }
}

enter image description here

我的问题是我需要编写什么sql查询,因此我将在sql server 2000中获得相同的输出。 假设我的数据以这种方式存储在sql server表中

Table : MyTable
------------------
ID  Title
-----------
1   Geo Prism GEO 1995 GEO* - ABS #16213899
2   Excavator JCB - ECU P/N: 728/35700
3   Geo Prism GEO 1995 - ABS #16213899
4   JCB Excavator JCB- ECU P/N: 728/35700
5   Geo Prism GEO,GEO 1995 - ABS #16213899 GEO
6   Maruti gear box #ABS 4587

我的编辑

我修复了你的sql中的一些语法问题....只是看看

CREATE FUNCTION [dbo].[Split] (@String varchar(8000), @Delimiter char(1))     
returns @temptable TABLE (items varchar(8000))       
as       
begin       
   declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

   while @idx!= 0       
   begin       
       set @idx = charindex(@Delimiter,@String)       
       if @idx!=0       
           set @slice = left(@String,@idx - 1)       
       else       
          set @slice = @String       

       if(len(@slice)>0)  
           insert into @temptable(Items) values(@slice)       

       set @String = right(@String,len(@String) - @idx)       
       if len(@String) = 0 break       
   end   
return       
end

DECLARE @Sterm varchar(MAX) 
SET @Sterm ='GEO JCB'
;WITH SearchResult (rnum, title)
as 
(   
(select 1 as rnum,'Geo Prism GEO 1995 GEO* - ABS #16213899' as title)
union all
(select 2 as rnum,'Excavator JCB - ECU P/N: 728/35700' as title)
union all
(select 3 as rnum,'Geo Prism GEO 1995 - ABS #16213899' as title)
union all
(select 4 as rnum,'JCB Excavator JCB- ECU P/N: 728/35700' as title)
union all
(select 5 as rnum,'Geo Prism GEO,GEO 1995 - ABS #16213899 GEO' as title)
union all
(select 6 as rnum,'dog' as title)
) 

select rnum, title from SearchResult
join 
( select lower(Items) as term 
  from dbo.Split(@Sterm , ' ')
) as search_terms
on lower(SearchResult.title) like '%' + search_terms.term +'%'
order by 
search_terms.term,
(select count(*)
from dbo.Split(lower(SearchResult.title),' ')
where Items = search_terms.term
) desc 

但它还没有满足我的要求。

1)查询应该返回搜索词以及那些与搜索词无关的结尾的行。

2)第二种排序应该就像那些行将首先出现在搜索词找到最大时间的地方,如GEO&amp; JCB。

根据搜索词的出现次数降序,你会错过第二个订单。如果你非常正确地看到图像,那么你可以看到我在这里问的是什么样的输出。感谢。

3 个答案:

答案 0 :(得分:2)

使用SQL Server Profiler获取正在运行的查询。

答案 1 :(得分:1)

单独使用SQL无法做到这一点。您需要一个存储例程来将标题字符串拆分为子字符串,然后SQL可以计算与您的搜索匹配的子字符串。

CREATE FUNCTION [dbo].[Split] (@String varchar(8000), @Delimiter char(1))     
returns @temptable TABLE (items varchar(8000))       
as       
begin       
  declare @idx int       
  declare @slice varchar(8000)       

  select @idx = 1       
    if len(@String)<1 or @String is null  return       

  while @idx!= 0       
  begin       
    set @idx = charindex(@Delimiter,@String)       
    if @idx!=0       
       set @slice = left(@String,@idx - 1)       
    else       
       set @slice = @String       

    if(len(@slice)>0)  
      insert into @temptable(Items) values(@slice)       

      set @String = right(@String,len(@String) - @idx)       
      if len(@String) = 0 break       
    end   
  return       
end

DECLARE @Sterm varchar(MAX) 
SET @Sterm ='GEO JCB'
;WITH SearchResult (rnum, title)
as 
(   
    (select 1 as rnum,'Geo Prism GEO 1995 GEO* - ABS #16213899' as title)
    union all
    (select 2 as rnum,'Excavator JCB - ECU P/N: 728/35700' as title)
    union all
    (select 3 as rnum,'Geo Prism GEO 1995 - ABS #16213899' as title)
    union all
    (select 4 as rnum,'JCB Excavator JCB- ECU P/N: 728/35700' as title)
    union all
    (select 5 as rnum,'Geo Prism GEO,GEO 1995 - ABS #16213899 GEO' as title)
    union all
    (select 6 as rnum,'dog' as title)
) 
select term,rnum, title
  from SearchResult
  left join 
     ( select lower(Items) as term 
         from dbo.Split(@Sterm,' ')
  ) as search_terms
  on lower(SearchResult.title) like '%' + search_terms.term +'%'
order by 
  isnull(search_terms.term,'ZZZZZZZZZZZZZ'),
  (select count(*)
     from dbo.Split(lower(SearchResult.title),search_terms.term)
  ) desc, 
  rnum desc

答案 2 :(得分:1)

您可以使用LINQ功能来获取SQL查询:

var ctx = new SomeDbDataContext();
var sw = new StringWriter();
ctx.Log = sw;

var items = from item in ctx.INVENTTABLEs
            where item.ITEMID.Length < 10
            select item;

foreach (var item in items)
{
   Console.WriteLine("{0}", item.ITEMID);
}

Console.WriteLine(sw.GetStringBuilder().ToString());
Console.ReadLine();