需要的SQL语句 - 来自范围但不在另一范围内的结果

时间:2015-10-09 15:12:20

标签: sql reporting-services

我有两张桌子。

  • 一个MEMBERS表,其中列出了有关成员和
  • 的所有详细信息
  • 第二个表,用于存储每列所有更改的历史记录
在MEMBERS表中

。例如,如果成员的状态在6月1日从Active更改为Frozen,则MEMBERCHANGES表将有一个条目说明该更改。

我需要创建一个SQL语句,列出状态为Freeze的所有MEMBER记录,这些记录已更改为日期范围内的状态,但第二个日期范围内没有任何更改。

例如,我需要所有在1月1日至5月1日期间更改为FREEZE状态但在5月2日至8月31日期间未对状态字段进行任何更改的成员。

SELECT MEMBERS.scancode
    ,MEMBERS.fname
    ,MEMBERS.lname
    ,MEMBERTYPES.description
    ,MEMBERS.STATUS
    ,MEMBERS.email
    ,MEMBERS.datejoin
    ,MEMBERS.dateexpire
    ,MEMBERS.daterenewal
    ,MEMBERCHANGES.datechange
    ,MEMBERCHANGES.newvalue
FROM MEMBERS
INNER JOIN MEMBERCHANGES ON MEMBERS.memid = MEMBERCHANGES.memid
INNER JOIN MEMBERTYPES ON MEMBERS.mtypeid = MEMBERTYPES.mtypeid
    AND NOT EXISTS (
        SELECT MEMBERS.memid
        FROM MEMBERS AS MEM2
        INNER JOIN MEMBERCHANGES ON MEM2.memid = MEMBERCHANGES.memid
        INNER JOIN MEMBERTYPES ON MEM2.mtypeid = MEMBERTYPES.mtypeid
        WHERE (MEMBERCHANGES.columnname = 'status')
            AND (MEMBERCHANGES.newvalue = 'F')
            AND (
                MEMBERCHANGES.datechange BETWEEN '2015-05-02'
                    AND '2015-08-31'
                )
            AND (MEM2.STATUS = 'F')
        )
WHERE (MEMBERCHANGES.columnname = 'status')
    AND (
        MEMBERCHANGES.datechange BETWEEN '2015-01-01'
            AND '2015-05-01'
        )
    AND (MEMBERS.STATUS = 'F')
    AND (MEMBERCHANGES.newvalue = 'F')

1 个答案:

答案 0 :(得分:1)

我用别名清理了你的查询并删除了一些我认为多余的东西。请原谅我改为小写。

select ...
from
    MEMBERS m
    inner join MEMBERCHANGES on mc.memid = m.memid
    inner join MEMBERTYPES on mt.mtypeid = m.mtypeid
where
        /* current status is Freeze */
        m.STATUS = 'F'

        /* changed to Freeze between certain dates */
    and mc.columnname = 'status'
    and mc.datechange between '2015-01-01' and '2015-05-01'
    and mc.newvalue = 'F'

        /* and no changes between later dates */
    and not exist (
        select 1
        from MEMBERCHANGES mc2
        where
                mc2.memid = mc.memid
            and mc2.columnname = 'status'
            and mc2.datechange between '2015-05-02' and '2015-08-31'
            and mc2.newvalue = 'F'
    )

由于目前的日期已经过了8月31日,我想知道你是否在检查过去一个半月内可能发生变化的当前状态时遇到了问题。我相信您知道您正在处理的数据。

当然,在第一个窗口期间状态可能已更改为冻结但后来在同一窗口中更改为其他内容也是可能的。然后它的当前状态可能是冻结,因为9月1日到现在的日期之间发生了变化。我不知道你是否需要检查这类事情,但是这个查询可能无法保证5月1日结束时的会员状态。