2012-07-18 57 views
4

我一直在为此工作2天,但无法弄清楚。我希望比我聪明的人会放弃这一点。Linq To Sql或SQL中的困难查询

比方说,我有如下表:

Rating: 
    Id | Name 
    1 | A 
    2 | B 
    3 | C 
    4 | D 
    5 | E 

Inspection: 
    Id | Date (mm/dd/yyyy) 
    1 | 01/04/2012 
    2 | 04/04/2012 
    3 | 28/03/2012 
    4 | 04/04/2012 

Observation: 
    Id | InspectionId | RatingId 
    1 | 2   | 3 
    2 | 1   | 2 
    3 | 4   | 3 
    4 | 2   | 1 
    5 | 3   | 3 
    6 | 1   | 2 

我想查询返回:

RatingName | Date(mm/dd/yyyy) | ObservationCount 
A   | 01/04/2012  | 0 
B   | 01/04/2012  | 1 
C   | 01/04/2012  | 1 
D   | 01/04/2012  | 0 
E   | 01/04/2012  | 0 
A   | 04/04/2012  | 1 
B   | 04/04/2012  | 0 
C   | 04/04/2012  | 2 
D   | 04/04/2012  | 0 
E   | 04/04/2012  | 0 
A   | 28/03/2012  | 0 
B   | 28/03/2012  | 0 
C   | 28/03/2012  | 1 
D   | 28/03/2012  | 0 
E   | 28/03/2012  | 0 

所以我需要观测的数量每个等级每个日期。是的,我需要有返回0观察记录,因为我在堆叠图表中使用这些数据,没有它们会引发错误。我已经设法得到上面的表,但没有返回0观察与下面的Linq To Sql查询的记录,但从这一点我卡住了。

MyDataContext DB = new MyDataContext(); 

var data = 
    (from r in DB.Ratings 
    join o in DB.Observations on r.Id equals o.RatingId into ro 

    from observation in ro.DefaultIfEmpty() 
    join i in DB.Inspections on observation.InspectionId equals i.Id into roi 

    from q in roi.DefaultIfEmpty() 
    group q by new { Name = r.Name, Date = q.Date } into grouped 
    select 
    new 
    { 
     RatingName = grouped.Key.Name, 
     Date = grouped.Key.Date, 
     ObservationCount = grouped.Count(x => x != null) 
    }).OrderBy(x => x.Date); 

我将不胜感激Linq To Sql或普通的旧SQL的答案,谢谢!

+0

我想感谢[sixlettervariables](http://stackoverflow.com/users/7116/sixlettervariables)帮助我获得这么大的进展 – Dean 2012-07-18 05:49:28

回答

4

您应该在两个参考表上尝试一个CROSS JOIN,然后OUTER JOIN回到您的'数据'表 - 然后检查Observation是否为空...然后分组和总和!

SELECT 
    [Name], 
    [Date], 
    SUM([Exists]) 
FROM 
(
SELECT 
    name, 
    [Date], 
    CASE WHEN o.Id IS NULL THEN 0 
     ELSE 1 
    END as [Exists] 
FROM 
    Rating r CROSS JOIN 
    Inspection i 
    LEFT OUTER JOIN Observation o 
     ON o.RatingId = r.Id AND o.InspectionId = i.Id 
) as [source] 
GROUP BY [Name], [Date] 
ORDER BY 
    [Date], 
    name 

翻译到LINQ将是类似的两个步骤的过程 - 获得所述内的结果集(检查观察是否是NULL),分组和求和之前。

+1

我:2天仍在工作。你:17分钟。谢谢! – Dean 2012-07-18 06:13:49

+0

有时你只需要一双新的眼睛:) – 2012-07-19 23:29:48