2013-10-14 54 views
-2

我寫在C#應用程序時,Visual Studio 2010
我有數據,如以下
尋找差距的數字在列表

Id tagNo TermNo 
1 1000 2 
2 1000 3 
3 1000 7 
4 1002 1 
5 1002 10 

我怎樣才能獲得通過LINQ或TSQL
以下結果

tagNo TermNo 
1000 1,4,5,6 
1002 2,3,4,5,6,7,8,9 

謝謝

+3

使用的GroupBy() – Jonesopolis

+1

我跟隨。爲什麼這是被拒絕投票? OP希望整數1或更大不在TermNo中,小於TermNo中的最大值。 – Paparazzi

回答

1

我會做類似如下:

var openTags = 
    from item in source       // Take the source items 
    group item by item.tagNo into g    // and group them by their tagNo. 
    let inUse = g.Select(_ => _.TermNo)   // Find all of the in-use tags 
    let max = inUse.Max()       // and max of that collection. 
    let range = Enumerable.Range(1, max - 1)  // Construct the range [1, max) 
    select new 
    {        // Select the following 
     TagNo = g.Key    // for each group 
     TermNo = range.Except(inUse) // find the available tags 
    }; 
1

我解決它使用LINQ,

var tagsList = sourceLists.Select(t => t.TagNo).Distinct().ToList(); 
foreach (var tagList in tagsList) 
{ 
var terminalList = sourceLists.Where(t => t.TagNo == tagList).Select(t => int.Parse(t.TermNo)).ToList();  
var result = Enumerable.Range(1, terminalList.Max()).Except(terminalList).ToList(); 
} 

但有誰能夠告訴我,如果有可能在TSQL或不 謝謝

0

一個提示去做使用Oracle如下 - (您可以在TSQL實現它也)

SELECT COLUMN_VALUE 
FROM TABLE(SYS.DBMS_DEBUG_VC2COLL(1,2,3,4,5,6,7,8,9,10)) 
MINUS 
SELECT '4' 
FROM DUAL; 

這將從提供​​的列表中篩選出'4'。 (1〜10)
同樣,你可以過濾掉你的項目(2,3,7,1,10)提供,你需要編寫查詢

+0

問題標記爲TSQL,您的解決方案無論如何不會工作。它只適用於1行 –

0

假設sourceLists實際上是一個EF實體,以下應該執行對數據庫中的所有

var terminalsByTag = sourceLists.GroupBy(x => x.TagNo) 
           .Select(x => new { 
            TagNo = x.Key, 
            Terminals = x.Select(t => Int32.Parse(t.TermNo)) 
           }); 
var result = Enumerable.Range(1, terminalsByTag.Max(g => g.Terminals.Max()).Except(g => g.Terminals).ToList(); 
+0

您錯過了新的關鍵字... –

+0

@SaeedAmiri yep我做了...更新。 – James

0

這是根據你的要求(修正)一個TSQL的解決方案:

declare @t table(Id int, tagNo int, TermNo int) 
insert @t values 
(1,1000,2), (2,1000,3), (3,1000,7), (4,1002,1), (5,1002,10) 

;with a as 
(
    select max(TermNo)-1 MaxTermNo, TagNo 
    from @t 
    group by TagNo 
), 
b as 
(
    select 1 TermNo, TagNo, MaxTermNo 
    from a 
    union all 
    select TermNo+1, TagNo, MaxTermNo 
    from b 
    where TermNo < MaxTermNo 
), 
c as 
(
    select TermNo, TagNo 
    from b 
    except 
    select TermNo, TagNo 
    from @t 
) 
select t.TagNo 
    ,STUFF(( 
     select ',' + cast(TermNo as varchar(9)) 
     from c t1 
     where t1.TagNo = t.TagNo 
     order by TermNo 
     for xml path(''), type 
    ).value('.', 'varchar(max)'), 1, 1, '') TermNo 
from c t 
group by t.TagNo 
option (maxrecursion 0) 

結果:

TagNo TermNo 
1000 1,4,5,6 
1002 2,3,4,5,6,7,8,9