2009-08-20 18 views
1

は、私は多くのテーブルのリレーションシップに多くを持ってグルーピング参加など、独自の一意なID、親テーブルからお客さまのIDや名前のタイトルの日付を、保持しています.. CUS_Phone_JCTは:独自のユニークなID、CUS_PhoneからidとCUS_Phone CUS_PhoneからIDを保持する:独自のIDを保持し、私が取得するために、クエリに参加していここでは、電話番号LINQ多くの左への多くは

すべての顧客名と電話番号:

var q = from c in CUS_Contact 
    join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
    from cp3 in cp2.DefaultIfEmpty() 
    join p in CUS_Phone on cp3.Phone_Id equals p.Id into p2 
    from p3 in p2.DefaultIfEmpty() 
    where c.Cus_Id == 9120 
    select new 
      { 
       c.Id, 
       c.Cus_Id, 
       c.Namefirst, 
       c.Namemiddle, 
       c.Namelast, 
       cp3.Phone.Phone, 
       c.Title, 
       c.Dept, 
       c.Des, c.Datecreate, 
       c.Dateupdate, 
       c.Usr_idcreate, 
       c.Usr_idupdate 
      }; 

foreach(var v in q){ 
Console.WriteLine(v.Id + "-" + v.Namefirst + "-" + v.Phone); 
} 

カスタマーごとの数値をグループ化するためにクエリを定式化する方法を教えてください。私は顧客ごとの数字のリスト(IEnumerableリスト)を持つ別個の顧客を見たいと思っています。 LINQPadのspanishOrdersクエリにも同様の例がありますが、注文ごとの注文詳細をグループ化しています。私のスキーマでこれを行う方法がわからない。ありがとう!


EDIT:ここでは最初の答えから出力されたSQL ...私は私はあなたのjoinCUS_Phoneに対するに加えてcp3.Phone.Phoneの使用で混乱ビットを、だよ

-- Region Parameters 
DECLARE @p0 Int SET @p0 = 4 
-- EndRegion 
SELECT (
    SELECT [t8].[id] 
    FROM (
     SELECT TOP (1) [t6].[id] 
     FROM [CUS_Contact] AS [t6] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t7] ON [t6].[id] = [t7].[Contact_Id] 
     WHERE [t2].[id] = [t6].[id] 
     ) AS [t8] 
    ) AS [Id], (
    SELECT [t11].[Cus_Id] 
    FROM (
     SELECT TOP (1) [t9].[Cus_Id] 
     FROM [CUS_Contact] AS [t9] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t10] ON [t9].[id] = [t10].[Contact_Id] 
     WHERE [t2].[id] = [t9].[id] 
     ) AS [t11] 
    ) AS [Cus_Id], (
    SELECT [t14].[namefirst] 
    FROM (
     SELECT TOP (1) [t12].[namefirst] 
     FROM [CUS_Contact] AS [t12] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t13] ON [t12].[id] = [t13].[Contact_Id] 
     WHERE [t2].[id] = [t12].[id] 
     ) AS [t14] 
    ) AS [Namefirst], (
    SELECT [t17].[namemiddle] 
    FROM (
     SELECT TOP (1) [t15].[namemiddle] 
     FROM [CUS_Contact] AS [t15] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t16] ON [t15].[id] = [t16].[Contact_Id] 
     WHERE [t2].[id] = [t15].[id] 
     ) AS [t17] 
    ) AS [Namemiddle], (
    SELECT [t20].[namelast] 
    FROM (
     SELECT TOP (1) [t18].[namelast] 
     FROM [CUS_Contact] AS [t18] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t19] ON [t18].[id] = [t19].[Contact_Id] 
     WHERE [t2].[id] = [t18].[id] 
     ) AS [t20] 
    ) AS [Namelast], (
    SELECT [t23].[title] 
    FROM (
     SELECT TOP (1) [t21].[title] 
     FROM [CUS_Contact] AS [t21] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t22] ON [t21].[id] = [t22].[Contact_Id] 
     WHERE [t2].[id] = [t21].[id] 
     ) AS [t23] 
    ) AS [Title], (
    SELECT [t26].[dept] 
    FROM (
     SELECT TOP (1) [t24].[dept] 
     FROM [CUS_Contact] AS [t24] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t25] ON [t24].[id] = [t25].[Contact_Id] 
     WHERE [t2].[id] = [t24].[id] 
     ) AS [t26] 
    ) AS [Dept], (
    SELECT [t29].[des] 
    FROM (
     SELECT TOP (1) [t27].[des] 
     FROM [CUS_Contact] AS [t27] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t28] ON [t27].[id] = [t28].[Contact_Id] 
     WHERE [t2].[id] = [t27].[id] 
     ) AS [t29] 
    ) AS [Des], (
    SELECT [t32].[datecreate] 
    FROM (
     SELECT TOP (1) [t30].[datecreate] 
     FROM [CUS_Contact] AS [t30] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t31] ON [t30].[id] = [t31].[Contact_Id] 
     WHERE [t2].[id] = [t30].[id] 
     ) AS [t32] 
    ) AS [Datecreate], (
    SELECT [t35].[dateupdate] 
    FROM (
     SELECT TOP (1) [t33].[dateupdate] 
     FROM [CUS_Contact] AS [t33] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t34] ON [t33].[id] = [t34].[Contact_Id] 
     WHERE [t2].[id] = [t33].[id] 
     ) AS [t35] 
    ) AS [Dateupdate], (
    SELECT [t38].[usr_idcreate] 
    FROM (
     SELECT TOP (1) [t36].[usr_idcreate] 
     FROM [CUS_Contact] AS [t36] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t37] ON [t36].[id] = [t37].[Contact_Id] 
     WHERE [t2].[id] = [t36].[id] 
     ) AS [t38] 
    ) AS [Usr_idcreate], (
    SELECT [t41].[usr_idupdate] 
    FROM (
     SELECT TOP (1) [t39].[usr_idupdate] 
     FROM [CUS_Contact] AS [t39] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t40] ON [t39].[id] = [t40].[Contact_Id] 
     WHERE [t2].[id] = [t39].[id] 
     ) AS [t41] 
    ) AS [Usr_idupdate], [t2].[id] AS [id2] 
FROM (
    SELECT [t0].[id] 
    FROM [CUS_Contact] AS [t0] 
    LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id] 
    GROUP BY [t0].[id] 
    ) AS [t2] 
WHERE ((
    SELECT [t5].[Cus_Id] 
    FROM (
     SELECT TOP (1) [t3].[Cus_Id] 
     FROM [CUS_Contact] AS [t3] 
     LEFT OUTER JOIN [CUS_Phone_JCT] AS [t4] ON [t3].[id] = [t4].[Contact_Id] 
     WHERE [t2].[id] = [t3].[id] 
     ) AS [t5] 
    )) = @p0 
GO 

-- Region Parameters 
DECLARE @x1 Int SET @x1 = 9327 
-- EndRegion 
SELECT [t2].[phone] AS [value] 
FROM [CUS_Contact] AS [t0] 
LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id] 
LEFT OUTER JOIN [CUS_Phone] AS [t2] ON [t2].[id] = [t1].[Phone_Id] 
WHERE @x1 = [t0].[id] 
GO 
-- Region Parameters 
DECLARE @x1 Int SET @x1 = 9328 
-- EndRegion 
SELECT [t2].[phone] AS [value] 
FROM [CUS_Contact] AS [t0] 
LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id] 
LEFT OUTER JOIN [CUS_Phone] AS [t2] ON [t2].[id] = [t1].[Phone_Id] 
WHERE @x1 = [t0].[id] 

答えて

3

です前者は後者を必要としないということを前提としています。それ以外の場合は、joincp3p3を入れて、それに応じてg.Select()を調整してください。

var q = from c in CUS_Contact 
     join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
     from cp3 in cp2.DefaultIfEmpty() 
     group new { c, cp3.Phone.Phone } by c.Id into g 
     let c = g.First().c 
     select new { 
         c.Id, 
         c.Cus_Id, 
         c.Namefirst, 
         c.Namemiddle, 
         c.Namelast, 
         Phones = g.Select(x => x.Phone) 
         c.Title, 
         c.Dept, 
         c.Des, c.Datecreate, 
         c.Dateupdate, 
         c.Usr_idcreate, 
         c.Usr_idupdate 
        }; 

foreach(var v in q) { 
    Console.WriteLine(v.Id + "-" + v.Namefirst); 
    foreach(var p in v.Phones) { 
     Console.WriteLine(" -" + p); 
    } 
} 

パフォーマンスを向上させるために暗闇の中でいくつかのショット:

var q = from c in CUS_Contact 
     join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
     from cp3 in cp2.DefaultIfEmpty() 
     group new { c, cp3.Phone.Phone } by c.Id into g 
     let c = g.First().c 
     select new { 
         c.Id, 
         c.Cus_Id, 
         c.Namefirst, 
         c.Namemiddle, 
         c.Namelast, 
         Phones = g.Select(x => x.Phone) 
         c.Title, 
         c.Dept, 
         c.Des, c.Datecreate, 
         c.Dateupdate, 
         c.Usr_idcreate, 
         c.Usr_idupdate 
        }; 

あなたはまた、試してみてください、あなたが接触IDで単にグループのことができるようにすべきである、と述べた

c.Idの代わりに複合キー(すべてのcフィールドを使用)でグループ化します。

 group cp3.Phone.Phone 
      by new { c.Id, c.Cus_Id, c.Namefirst, ETC } into g 
     let c = g.Key 
     select new { 
         ... 
         Phones = g.Select(p => p), 
         ... 
        } 

更新:あなたが必要とするものはすべてキーの中になければならないので、電話の値をグループ化するだけの複合キーの例を微調整しました。


アップデート2:あなたはかなりサブクエリを埋め込むことによって、物事を単純化することができるかもしれない。どちらかPhone.Phoneについて

var q = from c in CUS_Contact 
     select new { 
         c.Id, 
         c.Cus_Id, 
         c.Namefirst, 
         c.Namemiddle, 
         c.Namelast, 
         Phones = (from cp in CUS_Phone_JCT 
           where c.Id == cp.Contact_Id 
           select cp.Phone.Phone), 
         c.Title, 
         c.Dept, 
         c.Des, c.Datecreate, 
         c.Dateupdate, 
         c.Usr_idcreate, 
         c.Usr_idupdate 
        }; 
+0

イムわかりません。私は2番目を追加しない限り、テーブル名 "CUS_Phone"を出力します。このクエリは、以前と比較して約4秒かかり、10分の1秒未満しかかからないという点を除いて、うまく機能します。何か案は? – RyanOC

+0

生成されたSQLはどのように見えますか? – dahlbyk

+0

その大きすぎてここに入ることはできません。 600文字の制限と約4000です。 – RyanOC