根据会员资格,级别和到期日期或成员资格重复用户

时间:2015-12-11 17:31:37

标签: sql sql-server tsql

我们有一个包含重复用户记录的数据库,我需要根据以下几个因素选择“最佳”用户:

  1. 应在没有
  2. 的用户之前选择具有会员资格的用户
  3. 会员资格具有级别,并且在所有条件相同的情况下,应选择具有“最佳”会员级别的用户。
  4. 应在成员资格已过期的用户之前选择具有有效成员资格的用户。
  5. 基于这些条件,我提出了类似以下查询的内容(实际查询过于敏感)。

    SELECT TOP 1 u.[UserId]
        FROM [dbo].[Users] u
        LEFT OUTER JOIN [dbo].[UserMemberships] um
            ON u.[UserId] = um.[UserId]
        LEFT OUTER JOIN [dbo].[Memberships] m
            ON um.[MembershipId] = m.[MembershipId]
        WHERE u.[Email] = @Email
        ORDER BY m.[Order] ASC, um.[Expires] DESC, u.[Created] DESC
    

    我遇到的问题是会员的订购与到期。例如,如果有两个具有不同级别成员资格的重复用户,我通常会希望用户具有“最佳”成员资格级别(基于订单),但如果该成员资格已过期,我希望那个未过期的用户,即使它是较低的水平。但是,我不能简单地排除过期的会员资格,因为我需要选择具有会员资格的用户(即使它已过期)而不是会员资格。

    基本上,按会员顺序排序然后过期日期涵盖了大多数情况,但在这个特定情况下,订单应该是过期日期,然后是会员顺序。我可以对查询进行哪些修改以涵盖此边缘情况?

3 个答案:

答案 0 :(得分:2)

这样的事情怎么样?通过使用一些Case语句来创建数字排名列,您仍然可以在查询中保留过期记录,但为它们分配较低的值,以便必须首先评估活动成员资格:

SELECT TOP 1 u.[UserId], 
                Case um.[Expires]
                    When null then 9999      --Inactive Membership
                    When >= GetDate() then 1 --Expired Membership
                    Else 0                   --Active Membership
                End as ActiveRank, 
                Case m.[Order]
                    When null then 9999      --No Membership
                    Else Order               --Membership Ranking
                End as MembershipRank
  FROM [dbo].[Users] u
  LEFT OUTER JOIN [dbo].[UserMemberships] um
    ON u.[UserId] = um.[UserId]
  LEFT OUTER JOIN [dbo].[Memberships] m
    ON um.[MembershipId] = m.[MembershipId]
  WHERE u.[Email] = @Email             
  ORDER BY ActiveRank ASC, MembershipRank ASC, u.[Created] DESC

注意:我不太清楚你在Created字段中做了什么,所以我把它留在了订单中。

这意味着以下内容成立:

  1. ActiveRank会将订单拆分为两个不同的组...列表的上半部分将按活动成员资格排序,而较低的部分将按过期或不存在的成员资格排序。
  2. MembershipRank将根据排名优先排序(将空值或不存在的成员资格推送到列表过期成员资格部分的最底部。

答案 1 :(得分:1)

这是psuedocode,我将如何解决这个问题:

SELECT TOP 1 FROM (
  SELECT UserId, 1 AS rnk
  FROM Table
  WHERE {most desireable conditions are true}
  UNION ALL
  SELECT UserId, 2 AS rnk
  FROM Table
  WHERE {2nd most desireable conditions are true}
  UNION ALL
  SELECT UserId, 3 AS rnk
  FROM Table
  WHERE {3rd most desireable conditions are true}
  ...
) u
ORDER BY rnk ASC, {Secondary OrderBys like ExpDate etc}

答案 2 :(得分:1)

我之前所做的是使用案例陈述来为我的不同因素提供权重。然后,您可以根据总体重量选择要执行的操作。例如:

SELECT TOP 1
    CASE WHEN Expires >= GETDATE() THEN 10 ELSE 0 END
    +
    MemberLevel --Assuming this is some number that already ranks the member based on level
    +
    CASE WHEN IsMember THEN 2 ELSE 0 END MyRank
FROM [Your tables]
ORDER BY 1 Desc