带优先级的SQL选择
我需要为给定的FriendId选择前1个最有效的折扣。 我有以下表格: 折扣表-描述不同的折扣类型带优先级的SQL选择,sql,sql-server,select,Sql,Sql Server,Select,我需要为给定的FriendId选择前1个最有效的折扣。 我有以下表格: 折扣表-描述不同的折扣类型 DiscountId, Percent, Type, Rank 1 , 20 , Friend, 2 2 , 10 , Overwrite, 1 然后我有另外两个表(都列出了FriendID) 朋友 101 102 103 101 105 覆盖 101 102 103 101 105 我必须为给定的FriendI
DiscountId, Percent, Type, Rank
1 , 20 , Friend, 2
2 , 10 , Overwrite, 1
然后我有另外两个表(都列出了FriendID)
朋友
101
102
103
101
105
覆盖
101
102
103
101
105
我必须为给定的FriendId选择前1个最有效的折扣。因此,对于上述数据,这将是样本输出
Id = 101 => gets "Overwrite" discount (higher rank)
Id = 102 => gets "Friend" discount (only in friends table)
Id = 103 => gets "Friend" discount (only in friends table)
Id = 105 => gets "Overwrite" discount
Id = 106 => gets NO discount as it does not exist in neither Friend and overwrite tables
INPUT => SINGLE friendId (int).
OUTPUT => Single DISCOUNT Record (DiscountId, Percent, Type)
覆盖和朋友表是相同的。它们只保存ID列表(单列)具有多个相同结构的表通常是不好的做法,一个带有
ID
和类型的表就足够了,然后您可以在加入折扣表中使用它:
;WITH cte AS (SELECT ID,[Type] = 'Friend'
FROM Friends
UNION ALL
SELECT ID,[Type] = 'Overwrite'
FROM Overwrites
)
SELECT TOP 1 a.[Type]
FROM cte a
JOIN DiscountTable DT
ON a.[Type] = DT.[Type]
WHERE ID = '105'
ORDER BY [Rank]
注意,不存在的ID
值将不会返回。具有多个相同结构的表通常是不好的做法,一个具有ID
和类型的表就足够了,然后您可以在加入折扣表中使用它:
;WITH cte AS (SELECT ID,[Type] = 'Friend'
FROM Friends
UNION ALL
SELECT ID,[Type] = 'Overwrite'
FROM Overwrites
)
SELECT TOP 1 a.[Type]
FROM cte a
JOIN DiscountTable DT
ON a.[Type] = DT.[Type]
WHERE ID = '105'
ORDER BY [Rank]
注意,不存在的ID
值将不会返回。这将为您获得所有FriendID和最高级别的关联折扣。这是一个较老的黑客,不需要使用顶部或行编号
select
elig.FriendId,
min(Rank * 10000 + DiscountId) % 10000 as DiscountId
min(Rank * 10000 + Percent) % 10000 as Percent,
from
DiscountTable as dt
inner join (
select FriendId, 'Friend' as Type from Friends union all
select FriendId, 'Overwrite' from Overwrites
) as elig /* for eligible? */
on elig.Type = dt.Type
group by
elig.FriendId
这将为您获得所有最高级别的FriendID和同事折扣。这是一个较老的黑客,不需要使用顶部或行编号
select
elig.FriendId,
min(Rank * 10000 + DiscountId) % 10000 as DiscountId
min(Rank * 10000 + Percent) % 10000 as Percent,
from
DiscountTable as dt
inner join (
select FriendId, 'Friend' as Type from Friends union all
select FriendId, 'Overwrite' from Overwrites
) as elig /* for eligible? */
on elig.Type = dt.Type
group by
elig.FriendId
那么,106
将从何而来?Friends
和Overwrites
的结构实际上是相同的吗?或者仅仅是为了您的示例?这里有这么多的要点,您应该知道您需要发布更多的信息。您不能简单地从[表]中选择前1个[列]按ID订购?是朋友还是覆盖仅有的两个潜在折扣?或者以后还会添加更多?目前只使用这两个表。那么106
将从何而来?Friends
和Overwrites
的结构实际上是相同的吗?或者仅仅是为了您的示例?这里有这么多的要点,您应该知道您需要发布更多的信息。您不能简单地从[表]中选择前1个[列]按ID订购?是朋友还是覆盖仅有的两个潜在折扣?或者以后还会添加更多?目前只使用这两个表。这很有效。非常感谢。“如果有更多的“覆盖”表出现,我想我也可以合并它?”shawnt00同意,这就是我理解OP要寻找的。如果需要不同,我会使用行号()
和另一个cte来提取所有ID。这很有效。非常感谢。“如果有更多的“覆盖”表出现,我想我也可以合并它?”shawnt00同意,这就是我理解OP要寻找的。如果需要不同,我会使用行号()
和另一个cte来提取所有ID。