1

この質問の背後にある理由に関心のある方へ: 私は正常に動作する e コマース サイトを持っていますが、商品券の機能はありません。金銭的な 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

これは非常に単純化されたレイアウトですが、アイデアを示しています。最初のテーブルには、ユーザーのカート内のアイテムが一覧表示されます。製品ごとに 1 つのレコード (ただし、実際の製品には追加の詳細が異なる場合があります)。製品テーブルには、製品に関するその他の属性がありますが、簡単にするためにここにはリストしません。2 番目のテーブルは、このユーザー 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 つの行を提供し、上記の 2 つのテーブルをリンクする単一のクエリを作成することは可能ですか? または、これをスクリプトで処理する必要がありますか?

つまり、ユーザー 1 のカートには製品 1 が 2 回あり、無料の製品 1 が 1 つしか約束されていないため、クエリは、cartID 1 の一致する Gifts レコードを返す必要がありますが、cartID 3 は返しません。 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

  • ColdFusion 9

  • Windows 2000 AS

編集: 数量列が実際に問題を引き起こすように聞こえるので、Gifts テーブルに数量が存在しないと仮定して続行します。ただし、cartContents にはまだ存在している必要があります。

4

2 に答える 2

1

私はこれを行う別の方法を考えました。これは、追加のグループ化と結合を必要とするだけです。ただし、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

これは、ギフトが 1 つの製品ライン行のみに適用される場合に機能します。ギフトの数量が特定の行の数量よりも実際に多い場合、このクエリはそれを 1 つの行にのみ配置します。

于 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 に答える