【问题标题】:want to get same output by SQL/TSQL what i am getting by the LINQ query想要通过 SQL/TSQL 获得与我通过 LINQ 查询获得的相同的输出
【发布时间】:2012-08-04 17:52:02
【问题描述】:

我使用 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 查询,因此我将在 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 和 JCB。

你会根据搜索词的出现按降序错过第二个订单。如果你看得很清楚,那么你可以看到我在这里问的是什么类型的输出。谢谢。

【问题讨论】:

    标签: sql sql-server linq tsql


    【解决方案1】:

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

    【讨论】:

    • 我希望有些人会在 sql 中编写 linq 查询,因此我可以比在 sql server 2000 中运行查询并获得上述输出。为什么你建议我使用 sql server profiler。当我只需要 sql 时。
    • 因为 Profiler 会准确地显示 LINQ 向 SQL Server 发送的查询。这似乎完全符合您的要求。您不会一直使用 Profiler,它只会向您展示 - 一次 - LINQ 如何构建您想要运行的查询。
    • 我不知道如何使用分析器来查看生成了什么 sql。你能指导我吗?谢谢
    【解决方案2】:

    您不能仅使用 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
    

    【讨论】:

    • 假设搜索词存储在变量中,那么你的方法将是什么......因为在这里你对搜索词进行硬编码。假设搜索词是这样的声明 @Sterm varchar(MAX) SET Sterm ='GEO JCB' 任何帮助。
    • 我添加了对搜索词变量的支持。
    • 当然,如果要搜索一个真实的表,请将 SearchResult 替换为 MyTable。这将导致对每个术语进行全表扫描,但这会非常昂贵。
    • 感谢您的 sql....我在 sql server 中复制并运行您的 sql,然后它给出了太多的语法错误。你能纠正一下sql代码吗?谢谢
    • 您是否从示例中创建了 dbo.split 函数?你得到什么语法错误?我没有要测试的 SQL Server 数据库。
    【解决方案3】:

    您可以使用 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多