【问题标题】:finding members who have not renewed for current year查找当年未续订的会员
【发布时间】:2014-02-18 03:48:53
【问题描述】:

Membership 表包含每个成员每年 1 条记录(在此示例中进行了简化。

我想要尚未续订 2014 年的 2013 年成员。这与我逻辑上的结果一样接近,但我得到空结果

SELECT  Users.UserID
      , YEAR(Membership.MemYear) AS MemYear
      , Users.MailTo
      , Users.StreetAddress
      , Users.Address2
      , Users.City
      , StateLookup.State
      , Users.Zip
FROM Users INNER JOIN Membership 
ON Users.UserID = Membership.UserID 
INNER JOIN StateLookup 
ON Users.StateID = StateLookup.StateID 
where YEAR(Membership.MemYear) = '2013' 
and not exists 
(SELECT  Users.UserID, YEAR(Membership.MemYear) AS MemYear
       , Users.MailTo, Users.StreetAddress, Users.Address2
       , Users.City, StateLookup.State, Users.Zip
FROM Users INNER JOIN Membership AS Membership_1 
ON Users.UserID = Membership_1.UserID 
INNER JOIN StateLookup 
ON Users.StateID = StateLookup.StateID 
where YEAR(Membership_1.MemYear)='2014')

帮助表示赞赏!

【问题讨论】:

  • 为什么需要状态查找,'UserID' 不是唯一的吗?
  • Member 表中 MemYear 列的数据类型是什么??

标签: sql sql-server


【解决方案1】:

您可以使用 MAX(MemYear) 来查找拥有 2013 年最大 MemYear 的人。这意味着他们在 2013 年处于活跃状态并且没有续订。

SELECT Users.UserID
      , Users.MailTo
      , Users.StreetAddress
      , Users.Address2
      , Users.City
      , StateLookup.State
      , Users.Zip
FROM Users 
INNER JOIN Membership 
    ON Users.UserID = Membership.UserID 
INNER JOIN StateLookup 
    ON Users.StateID = StateLookup.StateID 
GROUP BY Users.UserID
      , Users.MailTo
      , Users.StreetAddress
      , Users.Address2
      , Users.City
      , StateLookup.State
      , Users.Zip
HAVING MAX(YEAR(Membership.MemYear)) = 2013

【讨论】:

    【解决方案2】:

    我认为如果“用户 ID”是唯一的,您可以这样做。

    SELECT Users.UserID  
      , YEAR(Membership.MemYear) AS MemYear  
      , Users.MailTo  
      , Users.StreetAddress  
      , Users.Address2  
      , Users.City  
      , StateLookup.State 
      , Users.Zip  
     FROM Users INNER JOIN Membership   
     ON Users.UserID = Membership.UserID   
     INNER JOIN StateLookup   
     ON Users.StateID = StateLookup.StateID   
     WHERE Membership.MemYear = '2013'   
     AND Users.UserID NOT IN  
       (SELECT UserID FROM Membership WHERE MemYear = '2014');
    

    【讨论】:

      【解决方案3】:

      尝试如下更改查询的底部:

      您忘记引用查询的另一层。假设您的查询的其余部分没问题,这应该可以解决该问题。

      SELECT Users.UserID,
             YEAR(Membership.MemYear) AS MemYear,
             Users.MailTo,
             Users.StreetAddress,
             Users.Address2,
             Users.City,
             StateLookup.State,
             Users.Zip
        FROM Users
       INNER JOIN Membership
          ON Users.UserID = Membership.UserID
       INNER JOIN StateLookup
          ON Users.StateID = StateLookup.StateID
       where YEAR(Membership.MemYear) = '2013'
         and not exists (SELECT x.UserID,
                     YEAR(Membership.MemYear) AS MemYear,
                     x.MailTo,
                     x.StreetAddress,
                     x.Address2,
                     x.City,
                     StateLookup.State,
                     x.Zip
                FROM Users x
               INNER JOIN Membership AS Membership_1
                  ON x.UserID = Membership_1.UserID
               INNER JOIN StateLookup
                  ON x.StateID = StateLookup.StateID
               where YEAR(Membership_1.MemYear) = '2014'
                 and x.UserID = Users.UserID)
      

      【讨论】:

      • 作为参考,您在存在子查询的选择列表中选择什么并不重要,您可能一直认为您使用的是 IN 子查询。解决该查询的另一种方法是将“不存在”更改为“不在”。
      【解决方案4】:
      SELECT  Users.UserID
            , MemYear 
            , Users.MailTo
            , Users.StreetAddress
            , Users.Address2
            , Users.City
            , StateLookup.State
            , Users.Zip
      FROM Users INNER JOIN Membership 
      ON Users.UserID = Membership.UserID 
      INNER JOIN StateLookup 
      ON Users.StateID = StateLookup.StateID 
      where Users.UserID  NOT IN 
                            (SELECT UserID
                             FROM Membership
                             where MemYear ='2014')
      

      【讨论】:

        【解决方案5】:
        SELECT  Users.UserID
          , YEAR(Membership.MemYear) AS MemYear
          , Users.MailTo
          , Users.StreetAddress
          , Users.Address2
          , Users.City
          , StateLookup.State
          , Users.Zip
        FROM Users INNER JOIN Membership ON Users.UserID = Membership.UserID 
        INNER JOIN StateLookup ON Users.StateID = StateLookup.StateID 
        where YEAR(Membership.MemYear) <= 2013   /* If it Integer you don't need '' */
        

        为什么要使用子查询?

        【讨论】:

        • 我添加了少于 2013 年或等于 2013 年的数字,而且它不包括 2014 年,简单点。
        • Membership 每年每个用户都有一条记录...这意味着您的查询可以返回 2014 年的人的结果。尽管您不一定需要第二个选择语句。我改为显示HAVING
        • @MikeSmithDev 我的赌注,没有查看重复名称的成员表,没错,有子句可以解决问题
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-25
        • 2023-03-08
        相关资源
        最近更新 更多