2013-08-29 51 views
2

使用SQL Server 2008的SQL:所有从一个表中的记录,所有记录从另一个,包括空

嗨,大家好,我有一个表称为Language所有我从这个表中需要的是LanguageID(1-10) 。
我有另一个表UserQuiz,我需要通过的ModuleIDCOUNT()
该计划将显示10个语言与4个模块与用户通过计数。

所以这将是40条记录(LanguageIDs * ModuleIDs)。
但并非所有语言都具有“所有模块”,因此没有任何记录。

我需要一个查询,将只填写缺少的模块,并将null的记录usercount。

到目前为止,我已经试过......

修订:: 29/08/2013 @上午10:35(北京时间)。

CREATE TABLE #CrossTable(
LanguageID int, 
ModuleID int 
) 
INSERT INTO #CrossTable 
SELECT LanguageID, ModuleID 
FROM 
RoundupAcademy.dbo.Languages 
CROSS JOIN 
RoundupAcademy.dbo.CurrentModules 
/*********************************************************************************/ 

/** get users via date and quiz **************************************************/ 
CREATE TABLE #userspassed(
userid int, 
passed int, 
moduleid int, 
languageid int 
) 
INSERT INTO #userspassed 
SELECT userprofile.UserId, passed, userquiz.moduleID, LanguageId 
FROM 
UserProfile 
LEFT JOIN 
UserQuiz 
ON 
UserProfile.UserId = UserQuiz.userID 
WHERE 
((Convert(datetime,LastLogin, 120) >= 
    Convert(datetime,@datefrom, 120) 
AND (Convert(datetime,LastLogin, 120) <= 
     convert(datetime,@datetoo, 120)))) 
AND 
(passed is null or passed = 1) 
/*********************************************************************************/ 

/**Get Modules per language count on users passed ********************************/ 
SELECT 
#CrossTable.languageID, 
#CrossTable.ModuleID, 
coalesce(COUNT(#userspassed.userID),0) as users 
FROM 
#CrossTable 
LEFT JOIN 
#userspassed 
ON 
#CrossTable.ModuleID = #userspassed.moduleID 
GROUP BY #CrossTable.LanguageID, #CrossTable.ModuleID 

/*********************************************************************************/ 

这确实带回了40条记录,但对于语言重复10次的模块“n”也有重复的用户(计数)。似乎只有4个值适用于模块1的10种语言(值94)和10的模块2(值89),10的模块3(值104)和10的模块4(值28)。

每个记录应该是不同的,但它似乎将相同的值应用于所有相同的模块。

已更新:: 29/08/2013 @ 11:05 am(GMT)。

我忘了补充

AND 
#CrossTable.LanguageID = #userspassed.languageid 

似乎现在的工作只是去检查值是否正确

+0

如果你没有地方模块的定义列表,那么就不能保证你会得到40条记录。也许没有用户通过任何组合。 要检查它,请将用户排除在等式之外并编写一个返回语言和模块的查询。如果你找到了你想要的40行,那么在之后添加用户并不是一个很大的跳跃。 –

+1

您需要使用'CROSS JOIN'来获取所有模块的所有语言的笛卡尔积。有关详细信息,请参阅http://technet.microsoft.com/zh-CN/library/ms190690(v=sql.105).aspx。 – MicSim

+0

@ StephenO'Flynn我使用我的语言表作为权威表,模块ID存储在自己的表中,唯一的问题是其具有模块ID和名称的一个表。那么,如何使用这张表格来取得所有40条记录呢? – lemunk

回答

2

也许链接到语言上也加入进来。此外,你不应该需要一个计数COALESCE:

SELECT 
    #CrossTable.languageID, 
    #CrossTable.ModuleID, 
    COUNT(#userspassed.userID) as users 
FROM 
    #CrossTable 
LEFT JOIN 
    #userspassed ON 
     #CrossTable.LanguageID = #userspassed.languageid 
     AND #CrossTable.ModuleeID = #userspassed.moduleid 
GROUP BY #CrossTable.LanguageID, #CrossTable.ModuleID 
+0

就像你发布我只是想出来哈哈 – lemunk

+0

为什么我不需要一个COALESCE? – lemunk

+0

因为如果没有记录,COUNT应该返回0。当你想用已知或具体的东西替换NULL时,使用COALESCE。 –

相关问题