2013-03-06 12 views
1

好吧,我不像我应该那样精通SQL,但我很熟悉连接,联盟等等是如何工作的,而且我不能提出解决方案为了这。我试图从两个不同的表中获取数据,但是猴子扳手是在我的结果集中右侧表格可能比我实际需要的行数多。我必须加入这两张表的唯一标准是电子邮件地址。代码如下:在两个SQL表之间连接数据

CREATE TABLE #PPEInfo(StudentEmail nvarchar(128), StudentName nvarchar(128), DevUnits int) 

INSERT INTO #PPEInfo (StudentEmail, DevUnits) 
SELECT e.StudentEmail AS Email, sum(ck.DevelopmentUnits) AS DevUnits 
FROM Enrollments e, CourseKeys ck 
WHERE e.CertGenerated = 'true' 
AND e.CourseId = ck.CourseId 
GROUP BY e.StudentEmail 
ORDER BY DevUnits DESC 

SELECT p.StudentEmail, p.DevUnits, s.StudentName 
FROM #PPEInfo p 
RIGHT OUTER JOIN Surveys s 
ON p.StudentEmail = s.StudentEmail 
ORDER BY DevUnits DESC, StudentName ASC 

DROP TABLE #PPEInfo 

问题是我收到多个学生姓名,因为他们在提交申请时可能没有使用过相同的姓名。例如:

Email Address James R. Salvati 
Email Address James Salvati 

,我已经想出唯一的办法是先填充我的临时表与电子邮件地址,然后查询表调查使用的名称“TOP(1)”只得到一个学生的名字。它确实有效,但它非常耗费CPU资源,而且我正在处理大量记录。下面的代码(虽然我不关心在这一点上只是想拿出东西DevUnits):

CREATE TABLE #PPEInfo(ID int IDENTITY(1,1), StudentEmail nvarchar(128), StudentName nvarchar(128), DevUnits int) 

INSERT INTO #PPEInfo (StudentEmail) 
SELECT DISTINCT StudentEmail FROM Enrollments 
WHERE CertGenerated = 'true' 

DECLARE @rowID int 
DECLARE @email nvarchar(128) 

SET @rowID = (SELECT max(ID) FROM #PPEInfo) 

WHILE (@rowID > 0) 
BEGIN 
    SET @email = (SELECT StudentEmail FROM #PPEInfo WHERE ID = @rowID) 
    UPDATE #PPEInfo 
    SET StudentName = (SELECT TOP(1) s.StudentName FROM Surveys s 
         WHERE s.StudentEmail = @email) 
    WHERE ID = @rowID 
    SET @rowID = @rowID - 1 
END 

SELECT * FROM #PPEInfo 
ORDER BY DevUnits DESC 

DROP TABLE #PPEInfo 

我从来没有真正张贴在这些板之一。我通常会找到解决方案或者找出一个解决方案,但是这个解决方案超出了我的SQL实力。

谢谢!

+0

您使用的是哪个版本的SQL Server? – 2013-03-07 00:53:35

回答

1

这取决于您想要确定在多个名称中选择哪个名称。一种可能的方式如下:

SELECT p.StudentEmail, p.DevUnits, MAX(s.StudentName) 
FROM #PPEInfo p 
RIGHT OUTER JOIN Surveys s 
ON p.StudentEmail = s.StudentEmail 
ORDER BY DevUnits DESC, StudentName ASC 
GROUP BY p.studentEmail, p.devUnits 

在这里,您通过电子邮件和单位分组,并抓住“MAX”学生姓名。

同样在你的第一个查询中,你应该停止使用隐式连接。

+0

谢谢安倍。这就像一个冠军。我从来没有想过对字符类型使用MAX。 – 2013-03-07 00:20:32

+0

我知道,有点奇怪,但它的作品。 – 2013-03-07 00:21:10

+0

让我紧张做这件事,因为虽然电子邮件*主要*仅由一个人使用......它不能保证。 – 2013-03-07 00:35:04

0

纠正我,如果我错了,但我敢肯定,你可以做到这一点,以达到你想要的东西:

select * from enrollments 
inner join coursekeys on 
enrollments.studentemail = coursekeys.studentemail 
where coursekeys.studentname=(
    select top 1 studentname from coursekeys 
    where studentemail=enrollments.studentemail 
); 

我没有在时刻访问SQL Server时,但我已经成功地在一台MySQL服务器上实现了这一点,并为您的表提供了类似的表格。