如何有效地使用SQL连接

时间:2013-07-30 03:47:11

标签: sql sql-server-2005

表格

作业

JobId, JobName  

JobDetail

JobDetailId, JobId, AcctNum, PerformDate

一个Job有许多JobDetailsJobId链接。

对于某些JobNames,(JobeName1,JobName2),我想要一个仅一个JobDetail 的列表,其中Performdate在过去6个月内。

对于上述标准,我应该得到两条记录。什么是正确的SQL语句?

我已经达到了这个目标,并没有得到正确的陈述。

SELECT 
    COUNT(J.JobId) 
FROM 
    Job J  
WHERE 
    J.JobName IN ('Doc1', 'Doc2')
GROUP BY 
    J.JobName

[编辑]
SQL Server 2005

[EDIT2]

SELECT 
    J.JobName, JD.AcctNum 
FROM 
    Job J  
JOIN JobDetail JD ON J.JobId = JD.JobId
WHERE 
    J.JobName IN ('DOC1', 'DOC2')
GROUP BY 
    J.JobName

这句话正在产生:

J.JobId在选择列表中无效...未包含在聚合函数中..

[EDIT3]
http://sqlfiddle.com/#!3/3ef21/1/0

我想通过PerformDate最新的AcctNum for Doc1& DOC2。

因此,根据SQLFIDDLE中的数据,我应该为每个JobName获得2个ROWS。

[EDIT4]
我的预期数据是来自JobDetail表的*行:
JobDetailId 1
jobDetailId 3

2 个答案:

答案 0 :(得分:4)

你走了:

SELECT COUNT(J.JobId) FROM Job J  
INNER JOIN JobDetails D ON J.JobId = D.JobId
WHERE J.JobName IN ('Jobname1', 'Jobname2') 
AND D.PerformDate >= DateAdd(mm, -6, getdate())
GROUP BY J.JobName

我在TSQL(SQL Server)中编写过这个。对于其他DBMS,您必须使用DateAdd(mm, -6, getdate())的相关功能。

更新:为AcctNumDOC1选择最新的DOC2

Select D.JobID, Acctnum from 
    JobDetail D Inner Join
    (
     SELECT J.JOBID, MAX(PerformDate) as LatestPerformDate FROM Job J
     INNER JOIN JobDetail D ON J.JobId = D.JobId
     WHERE J.JobName IN ('DOC1', 'DOC2') 
     Group by J.JobID
    ) X on D.JobID = X.JobID
    And D.PerformDate = X.LatestPerformDate

更新2 DOC2Job表格中显示两次,JobID不同。

Select D.JobID, Acctnum from 
JobDetail D Inner Join Job J on J.JobID = D.JobID
Inner join
(
 SELECT J.JOBname, MAX(PerformDate) as LatestPerformDate FROM Job J  
 INNER JOIN JobDetail D ON J.JobId = D.JobId
 WHERE J.JobName IN ('DOC1', 'DOC2')
 group by j.jobname
) X on J.JobName = X.JobName
And D.PerformDate = X.LatestPerformDate

问题中来自sqlfiddle中发布的输入数据的输出:

JOBID   ACCTNUM
--------------------
 1      1235
 4      1238

答案 1 :(得分:2)

SELECT j.*, d.*
FROM Job j
JOIN (SELECT JobId, MAX(PerformDate) maxDate
      FROM JobDetail
      WHERE PerformDate > DATEADD(mm, -6, GETDATE())
      GROUP BY JobId) md
ON j.JobId = md.JobId
JOIN JobDetail d
ON d.JobId = md.JobId AND d.PerformDate = md.maxDate
WHERE j.JobName IN ('DOC1', 'DOC2');

FIDDLE