0

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; }
}

ここに画像の説明を入力

私の質問は、SQL Server 2000 で同じ出力が得られる結果として、どのような SQL クエリを作成する必要があるかです。データがこのように 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) 2 番目の並べ替えは、GEO や JCB のように検索用語が最大の時間を見つけた行が最初に来るようにする必要があります。

検索語の発生に基づいて降順で 2 番目の順序を逃します。画像を正しく見ると、私がここで求めていた出力の種類がわかります。ありがとう。

4

3 に答える 3

2

SQL Server プロファイラーを使用して、実行中のクエリを取得します。

于 2012-08-04T17:53:15.280 に答える
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();
于 2012-08-04T20:10:25.157 に答える
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
于 2012-08-04T18:54:37.600 に答える