我正在尝试为以下情况制作SELECT语句,并且需要帮助才能生成此SELECT语句。这是SQL Server 2005。
运行select语句时,假设表中没有重复的PersonID,它应该返回SentDate为NULL的行。它将返回结果集,其状态为“初始记录”(因为尚未发送相同的人员ID)。导出数据后,SentDate将具有今天的日期。
现在假设已添加两个新行且PersonID重复。因此,当语句运行时,它应该仅返回新添加的两条记录,但状态为“跟进记录”,因为在先前的导出作业中导出了相同的人员。
以下是预期的示例:
初始表状态为:
的recordId PERSONID SentDate CreatedDate
1个1 NULL 2010年8月8日
2 2 NULL 2010年8月8日
3 3 NULL 2010年8月8日
首次运行时,应返回以下结果集:
的recordId PERSONID RECORDSTATUS
1 1'初始记录'
2 2'初始记录'
3 3'初始记录'
现在表的状态为:
的recordId PERSONID SentDate CreatedDate
1 1 8/9/2010 2010年8月8日
2 2 8/9/2010 2010年8月8日
3 3 8/9/2010 2010年8月8日
假设稍后在表中添加了一个新表,因此表值将为:
的recordId PERSONID SentDate CreatedDate
1 1 8/9/2010 2010年8月8日
2 2 8/9/2010 2010年8月8日
3 3 8/9/2010 2010年8月8日
4 2 NULL 2010年8月8日
5 2 NULL 2010年8月8日
现在这个查询应该返回
的recordId PERSONID RECORDSTATUS
4 2'跟进记录'
5 2'跟进记录'
答案 0 :(得分:2)
假设您的表名为Contacts:
SELECT RecordId, C1.PersonId, 'Initial Record' AS RecordStatus
FROM Contacts C1
INNER JOIN (SELECT PersonId, COUNT(PersonId) as PersonCount
FROM Contacts
GROUP BY PersonId) C2 ON
C1.PersonId = C2.PersonId
WHERE SentDate IS NULL AND PersonCount = 1
UNION
SELECT RecordId, C1.PersonId, 'Follow Up Record' AS RecordStatus
FROM Contacts C1
INNER JOIN (SELECT PersonId, COUNT(PersonId) as PersonCount
FROM Contacts
GROUP BY PersonId) C2 ON
C1.PersonId = C2.PersonId
WHERE SentDate IS NULL AND PersonCount > 1
ORDER BY RecordId
该查询的工作原理是假设如果一个PersonId只在表中存在一次,则它是一个初始记录;否则,这是一个跟进记录。
修改强>
受欢迎的需求,现在减少100%的UNION!
SELECT RecordId, C1.PersonId,
CASE WHEN PersonCount > 1 THEN 'Follow Up Record'
WHEN PersonCount = 1 THEN 'Initial Record' END
AS RecordStatus
FROM Contacts C1
INNER JOIN (SELECT PersonId, COUNT(PersonId) as PersonCount
FROM Contacts
GROUP BY PersonId) C2 ON
C1.PersonId = C2.PersonId
WHERE SentDate IS NULL
编辑2
这可能是矫枉过正,但这是我第一次看到CTE版本:
With PersonCountCTE (PersonId, PersonCount) AS
(
SELECT PersonId, COUNT(PersonId) AS PersonCount
FROM Contacts
GROUP BY PersonId
)
SELECT RecordId, C1.PersonId,
CASE WHEN PersonCount > 1 THEN 'Follow Up Record'
WHEN PersonCount = 1 THEN 'Initial Record' END
AS RecordStatus
FROM Contacts C1
INNER JOIN PersonCountCTE C2 ON C1.PersonId = C2.PersonId
WHERE SentDate IS NULL
答案 1 :(得分:1)
With Data As
(
Select RecordId, PersonId, SentDate, CreatedDate
, Row_Number() Over ( Partition By PersonId
Order By CreatedDate Desc, RecordId Desc ) As Seq
From #Test
)
Select RecordId, PersonId
, Case
When Seq = 1 Then 'Initial Record'
Else 'Follow up Record'
End As RecordStatus
From Data
Where SentDate Is Null