|
質問者さんは去ってしまわれたような気がしますが、このまま中途で終わっても何ですので、
自分が質問者さんのレスから最初に想像した条件 (1) 〜 (3) に以下のように (4) の条件
(多分、朱鷺さんの考えと同じ)を追加した場合のコードをアップしておきます。
(1) テーブル A と B で key1 が同じ、
(2) テーブル A と B で time が B の方が遅いか同じ、
(3) テーブル A で key2 が "A-1"、
(4) 上記 (1) 〜 (3) の結果、key1 が同じレコードが複数ある場合は B.time が最も古いもののみ取得。
下のコードでコメントの「// B の各グループの中で time が最小の B を抽出」以下がそれです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleAppLinq2
{
public class A
{
public string key1 { get; set; }
public string key2 { get; set; }
public DateTime time { get; set; }
}
public class B
{
public string key1 { get; set; }
public string item { get; set; }
public DateTime time { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<A> listA = new List<A> {
new A { key1 = "A", key2 = "A-1", time = DateTime.Parse("2016/1/1") },
new A { key1 = "A", key2 = "A-2", time = DateTime.Parse("2016/1/1") },
new A { key1 = "A", key2 = "A-3", time = DateTime.Parse("2016/1/1") },
new A { key1 = "B", key2 = "A-1", time = DateTime.Parse("2016/1/11") },
new A { key1 = "B", key2 = "A-2", time = DateTime.Parse("2016/1/16") },
new A { key1 = "C", key2 = "A-1", time = DateTime.Parse("2016/1/21") }
};
List<B> listB = new List<B> {
new B { key1 = "A", item = "あ", time = DateTime.Parse("2016/1/4") },
new B { key1 = "A", item = "い", time = DateTime.Parse("2016/1/14") },
new B { key1 = "A", item = "う", time = DateTime.Parse("2016/1/24") },
new B { key1 = "B", item = "え", time = DateTime.Parse("2016/1/5") },
new B { key1 = "B", item = "お", time = DateTime.Parse("2016/1/15") },
new B { key1 = "B", item = "か", time = DateTime.Parse("2016/1/25") },
new B { key1 = "C", item = "き", time = DateTime.Parse("2016/1/6") },
new B { key1 = "C", item = "く", time = DateTime.Parse("2016/1/16") },
new B { key1 = "C", item = "け", time = DateTime.Parse("2016/1/26") }
};
// 最初の想像と同じ条件で抽出
var result = from b in listB
join a in listA
on b.key1 equals a.key1
where b.time >= a.time && a.key2 == "A-1"
select new { Akey2 = a.key2, Bkey1 = b.key1, Bitem = b.item, Btime = b.time };
foreach (var x in result)
{
Console.WriteLine("A.key2={0}, B.key1={1}, B.item={2}, B.time={3}", x.Akey2, x.Bkey1, x.Bitem, x.Btime);
}
/*
結果は同じく:
A.key2=A-1, B.key1=A, B.item=あ, B.time=2016/01/04 0:00:00
A.key2=A-1, B.key1=A, B.item=い, B.time=2016/01/14 0:00:00
A.key2=A-1, B.key1=A, B.item=う, B.time=2016/01/24 0:00:00
A.key2=A-1, B.key1=B, B.item=お, B.time=2016/01/15 0:00:00
A.key2=A-1, B.key1=B, B.item=か, B.time=2016/01/25 0:00:00
A.key2=A-1, B.key1=C, B.item=け, B.time=2016/01/26 0:00:00
*/
// B の key1 でグループ化してみる
var result2 = from b in listB
join a in listA
on b.key1 equals a.key1
where b.time >= a.time && a.key2 == "A-1"
group b by b.key1 into newGroup
select newGroup;
foreach (var key1Group in result2)
{
Console.WriteLine("Key: {0}", key1Group.Key);
foreach (var b in key1Group)
{
Console.WriteLine("\t{0}, {1}", b.item, b.time);
}
}
/*
結果は:
Key: A
あ, 2016/01/04 0:00:00
い, 2016/01/14 0:00:00
う, 2016/01/24 0:00:00
Key: B
お, 2016/01/15 0:00:00
か, 2016/01/25 0:00:00
Key: C
け, 2016/01/26 0:00:00
*/
// B の各グループの中で time が最小の B を抽出
var result3 = from b in listB
join a in listA
on b.key1 equals a.key1
where b.time >= a.time && a.key2 == "A-1"
group b by b.key1 into newGroup
from c in newGroup
where c.time == newGroup.Min(x => x.time)
select c;
foreach (var x in result3)
{
Console.WriteLine("B.key1={0}, B.item={1}, B.time={2}", x.key1, x.item, x.time);
}
/*
結果は:
B.key1=A, B.item=あ, B.time=2016/01/04 0:00:00
B.key1=B, B.item=お, B.time=2016/01/15 0:00:00
B.key1=C, B.item=け, B.time=2016/01/26 0:00:00
*/
}
}
}
|