从表B中删除重复到表A上的唯一行的重复项

时间:2016-12-07 20:02:00

标签: sql tsql ms-access

我仍然是SQL的新手,我的查询达到了复杂程度,我无法完全隔离我需要的内容或我称之为的问题。因此,我在寻找答案时遇到了很多麻烦。查询位于底部以保持干净的阅读空间。此查询的目标是根据提供的日期返回305后的状态,该状态由人员列表修改。

我没想到的是,如果一个成员在列表中的一个成员之前进入305两次,那么有两行,我的计数变得怪异。以下是它目前给出的一个例子:

+----------+------------+---------+----------+------------+---------+----------+
| MemberID | OldStatus  | OldUser |  OldDt   | NewStatus  | NewUser |  NewDt   |
+----------+------------+---------+----------+------------+---------+----------+
| member1  |        305 | A       | 11/9/16  |        801 | K       | 11/10/16 |
| member1  |        305 | B       | 9/9/16   |        801 | K       | 11/10/16 |
| member2  |        305 | A       | 10/3/16  |        205 | D       | 10/7/16  |
| member2  |        305 | A       | 10/11/16 |        310 | D       | 10/14/16 |
+----------+------------+---------+----------+------------+---------+--------- +

但我希望它看起来像这样:

+----------+------------+---------+----------+------------+---------+----------+
| MemberID | OldStatus  | OldUser |  OldDt   | NewStatus  | NewUser |  NewDt   |
+----------+------------+---------+----------+------------+---------+----------+
| member1  |        305 | A       | 11/9/16  |        801 | K       | 11/10/16 |
| member2  |        305 | A       | 10/3/16  |        205 | D       | 10/7/16  |
| member2  |        305 | A       | 10/11/16 |        310 | D       | 10/14/16 |
+----------+------------+---------+----------+------------+---------+----------+

话虽如此,我大致了解为什么我的加入会这样做。我不明白的是如何让它停止这样做,但只有当表B对于同一个成员是相同的时候。同一成员可以出现两次,但前提是表B的结果与更改时的结果不同。

此外,我的查询有点拼凑在一起。这是我解决问题的方法,但看起来真的很多余。如果任何人对我的代码有更优雅或更强大的解决方案或改进,我将不胜感激。我使用的是Access 2010和MS SQL,无法访问后端工具。

谢谢!

SELECT DISTINCT A.memberid,
                A.statuscd   AS 305_Status,
                A.updateuser AS 305_User,
                A.updatedt   AS 305_Date,
                B.statuscd   AS New_Status,
                B.updateuser AS New_User,
                B.updatedt   AS New_Date
FROM   v_queue_history AS A
       INNER JOIN v_queue_history AS B
               ON ( A.memberid = B.memberid
                    AND A.updatedt >= ( DATE() - 365 )
                    AND A.statuscd = '305'
                    AND B.statuscd <> '305'
                    AND B.updateuser IN ( 'a', 'd',
                                          'g',
                                          'h',
                                          'j', 'k', 'p'
                                          ,
                                          'm'
                                          ,
                                          's', 'w',
                                          'k' )
                    AND B.updatedt > A.updatedt )
WHERE  B.updatedt = (SELECT Min(updatedt)
                     FROM   v_queue_history AS C
                     WHERE  C.memberid = A.memberid
                            AND C.updatedt > A.updatedt
                            AND C.statuscd <> "305")
       AND ( Year(B.updatedt) * 53 + Datepart("m", B.updatedt) =
                   Year(DATE()) * 53 + Datepart("m", DATE())
                   - [how many months ago would you like to look?] ); 

1 个答案:

答案 0 :(得分:0)

我认为您只需要找到305状态的最大日期。

SELECT DISTINCT A.memberid,
                A.statuscd   AS 305_Status,
                A.updateuser AS 305_User,
                A.updatedt   AS 305_Date,
                B.statuscd   AS New_Status,
                B.updateuser AS New_User,
                B.updatedt   AS New_Date
FROM   v_queue_history AS A
       INNER JOIN v_queue_history AS B
               ON ( A.memberid = B.memberid
                    AND A.updatedt >= ( DATE() - 365 )
                    AND A.statuscd = '305'
                    AND B.statuscd <> '305'
                    AND B.updateuser IN ( 'a', 'd',
                                          'g',
                                          'h',
                                          'j', 'k', 'p'
                                          ,
                                          'm'
                                          ,
                                          's', 'w',
                                          'k' )
                    AND B.updatedt > A.updatedt )
WHERE  B.updatedt = (SELECT Min(updatedt)
                     FROM   v_queue_history AS C
                     WHERE  C.memberid = A.memberid
                            AND C.updatedt > A.updatedt
                            AND C.statuscd <> "305")
       AND A.updatedt = (SELECT MAX(updatedt)
                         FROM v_queue_history AS D
                         WHERE  D.memberid = A.memberid
                            AND D.updatedt < B.updatedt
                            AND D.statuscd = "305")
       AND ( Year(B.updatedt) * 53 + Datepart("m", B.updatedt) =
                   Year(DATE()) * 53 + Datepart("m", DATE())
                   - [how many months ago would you like to look?] );