检查购物车的适用组查询

时间:2012-08-03 07:16:47

标签: sql-server sql-server-2008 tsql

我有一个折扣检查条件的问题。我的表格结构如下:

购物车(id, customerid, productid)     群组表格(groupid, groupname, discountamount)     群组产品表格(groupproductid, groupid, productid)

在下订单时,购物车中会有多件商品,如果该商品包含所有产品购物车,我想检查那些最顶级商品的商品吗?

示例: 如果第1组包含2个产品,并且这两个产品存在于购物车表中,则应返回第1组折扣。

请帮助

1 个答案:

答案 0 :(得分:0)

这很棘手,没有真正的表定义和样本数据。所以我做了一些:

create table Carts(
    id int,
    customerid int,
    productid int
)
create table Groups(
    groupid int,
    groupname int,
    discountamount int
)
create table GroupProducts(
    groupproductid int,
    groupid int,
    productid int
)

insert into Carts (id,customerid,productid) values
(1,1,1),
(2,1,2),
(3,1,4),
(4,2,2),
(5,2,3)
insert into Groups (groupid,groupname,discountamount) values
(1,1,10),
(2,2,15),
(3,3,20)
insert into GroupProducts (groupproductid,groupid,productid) values
(1,1,1),
(2,1,5),
(3,2,2),
(4,2,4),
(5,3,2),
(6,3,3)

;With MatchedProducts as (
    select
        c.customerid,gp.groupid,COUNT(*) as Cnt
    from
        Carts c
            inner join
        GroupProducts gp
            on
                c.productid = gp.productid
    group by
        c.customerid,gp.groupid
), GroupSizes as (
    select groupid,COUNT(*) as Cnt from GroupProducts group by groupid
), MatchingGroups as (
    select
        mp.*
    from
        MatchedProducts mp
            inner join
        GroupSizes gs
            on
                mp.groupid = gs.groupid and
                mp.Cnt = gs.Cnt
)
select * from MatchingGroups

产生这个结果:

customerid  groupid     Cnt
----------- ----------- -----------
1           2           2
2           3           2

我们在这里所做的事情被称为“关系分工” - 如果你想在别处寻找那个词。在我目前的结果中,每个客户只匹配一个组 - 如果有多个匹配,我们需要一些打破平局的条件来确定要报告的组。我在评论中提示了两条建议(最低groupid或最高discountamount)。您对“之前添加”的回复没有帮助 - 我们没有包含组添加日期的列。行在SQL中没有固有的顺序。

我们会在MatchingGroups和最终选择的定义中打破平局:

MatchingGroups as (
    select
        mp.*,
        ROW_NUMBER() OVER (PARTITION BY mp.customerid ORDER BY /*Tie break criteria here */) as rn
    from
        MatchedProducts mp
            inner join
        GroupSizes gs
            on
                mp.groupid = gs.groupid and
                mp.Cnt = gs.Cnt
)
select * from MatchingGroups where rn = 1