1

对于那些对这个问题背后的推理感兴趣的人:我有一个运行良好的电子商务网站,但没有礼券功能。添加货币 GC 应该非常简单,但我也希望允许赠送特定产品(听起来很奇怪,但与我的行业相关)。因此,我计划创建一个新表来存放与特定用户和产品相关联的礼券,并且我需要一种有效的方法来评估购物车和结帐页面上的该表。

想象一下存在类似于以下内容的表:

CartContents
CartID          Integer (Unique sequential row identifier)
UserID          Integer
ProductID       Integer
Quantity        Integer

Gifts
GiftID          Integer (Unique sequential row identifier)  
ProductID       Integer
UserID          Integer
Quantity        Integer

这是一个过于简化的布局,但展示了这个想法。第一个表格列出了用户购物车中的物品;每个产品一条记录(尽管实际产品会有可能会有所不同的其他详细信息)。产品表还有更多关于产品的属性,但为了简单起见,我没有在这里列出。第二个表是一组礼券,每个礼券用于特定产品,已提供给该用户 ID。

表数据可能如下所示:

CartContents
CartID          UserID      ProductID       Quantity
1               1           1               1
2               1           2               2
3               1           1               2
4               2           3               1

Gifts
ProductID       UserID      Quantity
1               1           1
2               1           1
3               3           1

考虑到每个礼物只能链接到每个购物车项目一次,是否可以构建一个查询,为每个购物车项目提供一行并链接上述两个表?或者这需要在脚本中处理吗?

换句话说,因为用户 1 在他们的购物车中有两次产品 1,并且他们只被承诺过一件免费产品 1,所以查询应该返回与 cartID 1 匹配的 Gifts 记录,而不是 cartID 3。查询,拉取用户 ID 1、会返回:

CartID      ProductID       Quantity        unpaidQuantity
1           1               1               0
2           2               2               1
3           1               2               2

或者

CartID      ProductID       Quantity        unpaidQuantity
1           1               1               1
2           2               2               1
3           1               2               1

我意识到这个问题有不止一个“正确”答案这一事实引发了一个危险信号。实际上,每个 GC 应用于哪个购物车记录并不重要,因为最终结果(价格)将是相同的。我很高兴地说“第一个”(最低购物车 ID)是应该链接的。

我的假设是,数据库在这方面的效率将比我编写的任何脚本都要高得多;我什至愿意打赌有一些我从未听说过专门为它设计的疯狂类型的加入。我还假设任何这样的 ColdFusion 脚本可能有些复杂,因此需要相当多的开发和测试时间,而单个查询可能相对简单(尽管显然超出了我有限的 SQL 能力)。如果我在这方面不正确,我也将不胜感激。

我的设置,如果重要的话:

  • MySQL 5.0

  • 冷融合 9

  • 视窗 2000 作为

编辑: 听起来数量列真的会引起问题,所以让我们继续假设礼品表上不存在数量。但是,它仍然必须存在于 cartContents 上。

4

2 回答 2

1

我想到了另一种方法,只需要额外的 group by 和 join。但是,它需要 CartContents 上的唯一 ID。我不确定这是 CartId 应该是什么。但是,似乎一个用户可以拥有多个购物车,所以我认为不会。

这个想法是识别每个购物车中给定产品的第一条记录。然后,在加入礼物时使用此信息。

select CartID, UserID, ProductID, Quantity, FirstCCId  
from CartContents cc join
     (select CartID, UserID, ProductID, min(CartContentsId) as FirstCCId
      from CartContents cc
      group by CartID, UserID, ProductID
     ) ccmin
     on cc.CartId = ccmin.CartId and cc.UserId = ccmin.UserId and
        cc.ProductId = ccmin.ProductId left outer join
     Gifts g
     on cc.ProductID= g.ProductId and cc.UserID = g.userId and
        cc.CartContentsId = ccmin.FirstCCId

当礼品仅应用于一个产品线行时,此方法有效。如果礼物的数量实际上大于任何给定行上的数量,则此查询仍然只将其放在一行上。

于 2012-07-18T18:15:46.267 回答
0

这行得通吗?

select c.cartid, c.productid, c.quantity, c.quantity -
         case 
           when (select sum(c2.quantity) from CartContents c2 
                 where c.userid = c2.userid 
                   and c.productid = c2.productid 
                   and c.cartid < c2.cartid) < 
                 (select g.quantity from gifts g 
                  where c.userid = g.userid 
                    and c.productid = g.productid) then
             (select g.quantity from gifts g 
              where c.userid = g.userid 
                and c.productid = g.productid) - 
             (select sum(c2.quantity) from CartContents c2 
              where c.userid = c2.userid 
                and c.productid = c2.productid 
                and c.cartid < c2.cartid) 
           else 0 
         end UnpaidQuantity
from CartContents c
where userid = 1
于 2012-07-18T18:35:26.363 回答