如何将带有子查询的复杂SQL查询转换为LINQ

时间:2011-06-16 19:02:29

标签: sql linq translation

如何将以下查询转换为Linq表达式?

SELECT p.playerid,
       (SELECT SUM(d.runs)
        FROM   deliveries d
               INNER JOIN overs o ON d.overid = o.overid
        WHERE  o.isbatting = 1
               AND o.gameid = 5
               AND d.player_playerid = playerid) AS runsfor,
       (SELECT SUM(d.runs)
        FROM   deliveries d
               INNER JOIN overs o
                 ON d.overid = o.overid
        WHERE  o.isbatting = 0
               AND o.gameid = 5
               AND d.player_playerid = playerid) AS runsagainst,
       ( (SELECT SUM(d.runs)
          FROM   deliveries d
                 INNER JOIN overs o ON d.overid = o.overid
          WHERE  o.isbatting = 1
                 AND o.gameid = 5
                 AND d.player_playerid = playerid) -
         (SELECT SUM(d.runs)
          FROM   deliveries d
                 INNER JOIN overs o ON d.overid = o.overid
          WHERE  o.isbatting = 0
                 AND o.gameid = 5
                 AND d.player_playerid =
                     playerid) ) AS runscontributed
FROM   deliveries d
       INNER JOIN players p ON d.player_playerid = p.playerid
       INNER JOIN overs o   ON d.overid = o.overid
WHERE  o.gameid = 1
GROUP  BY p.playerid  

生成的结果如下:

2   13  16  -3
4   -5  18  -23
5   -6  11  -17
7   4   1   3
8   5   7   -2
9   12  17  -5
10  -4  24  -28
12  19  1   18

1 个答案:

答案 0 :(得分:4)

首先简化。

SELECT d.*, o.*
FROM   deliveries d
INNER JOIN overs o ON d.overid = o.overid
var joined = from d in deliveries
             join o in overs on d.overid equals o.overid
             select new { d, o };

然后简化一些......

SELECT SUM(d.runs)
FROM   deliveries d
INNER JOIN overs o ON d.overid = o.overid
WHERE  o.isbatting = 1
       AND o.gameid = 5
       AND d.player_playerid = playerid
(from j in joined
 where j.o.isBatting 
 && j.o.gameId == 5 
 && j.d.player.playerId == playerId
 select j.d.runs).Sum();

泡沫,冲洗,重复:

var joined = from d in deliveries
             join players p on d.player_playerid equals p.playerid
             join o in overs on d.overid equals o.overid;
             where j.o.gameid = 1
             select new { p, d, o };

var _runsfor = from j in joined
               where j.o.isBatting 
               && j.o.gameId == 5 
               && j.d.player.playerId == some_player_id
               select j;

var ungrouped = from j in joined
                select new 
                {
                    playerId = j.p.playerid,
                    runsFor = _runsfor.Where(r => r.p.playerId == j.p.playerId)
                                      .Sum(jn => jn.d.runs),
                    runsAgainst = //etc...
                };      

var grouped = from u in ungrouped 
              group new { u.runsFor, u.runsAgainst, /* etc... */ }
              by u.playerId into player
              select player;

我不确定这会做你想做的事,但它应该给你一个跳跃点。

请勿直接使用此代码;我是徒手写的,我不确定它会在没有一些调整的情况下第一次运行。这里的真正要点是简化。将SQL查询分成更小的组并为其编写LINQ。然后写一些LINQ将它们绑在一起。这样做的能力是关于LINQ的最好的事情之一。