0

トランザクションデータを取得して、分析のニーズを満たすためにクレンジングしようとしています。トランザクションをデータベースに記録する方法にはいくつかの制限があり、私はそれらの制限を回避しようとしています。

顧客が複数の製品を注文した場合、トランザクションデータベースは複数の製品をリンクしません。各製品には一意の販売IDがありますが、複数の販売IDを1つの注文にグループ化する方法はありません。サンプルは次のとおりです。

OrderID   MultOrderID   CustomerID  SalesDate   SalesTime   ProductID   ProductCost ShippingCost
6082346                 7661X0A     2012-06-12  959         105         99.99       7.95
6082347   5809812YY6Y   T891002     2012-06-12  1005        222         99.95       7.95
6082348   5809812YY6Z   T891002     2012-06-12  1005        273         22.95       1.00
6082349   5809812YY71   T891002     2012-06-12  1005        285         499.95      1.00
6082350   5809812YY72   T891002     2012-06-12  1005        172         49.95       1.00
6082351   5809812YY73   T891002     2012-06-12  1005        105         99.99       7.95
6082352   5809812YY74   X637251     2012-06-12  1010        285         499.95      7.95
6082353   5809812YY75   X637251     2012-06-12  1010        30          1024.99     1.00
6082354                 T512AT0     2012-06-12  1017        172         49.95       7.95

このトランザクションシステムの追加の制限は、4つを超える製品を一緒に出荷できないことです。顧客が5つの製品を注文した場合、4つの製品が一緒に出荷され(1つの配送料が請求され)、残りの製品は別々に出荷され、別の配送料が請求されます(はい、ビジネス全体がこのレガシーシステム全体を再構築したいと考えています... 。)。

私が判断しようとしているのは、注文ごとに出荷される製品の数と、製品コストと送料の合計です。

MultOrderIDの最後の4文字を見ると、それが連続していることがわかります。YY6YはYY6Zになり、YY71、YY72にロールオーバーします。ロジックは標準化されています。CustomerID、SalesDate、SalesTimeが同じであれば、製品をペアにすることができます。私が知らないのは、これをどのように達成できるかということです。

これを実現する方法は、CustomerID、SalesDate、SalesTimeで注文を分割することだと思います。次に、、for-loopまたはそのようなものを取得して、個々のエントリを循環します。次に、MultOrderIDの最後の4文字を探して、次のように言います。-1、2、3が同じで、4番目の文字が前の注文の4番目の文字の後にある場合は、最大4つの注文でペアにします。orderIDが範囲内の5番目から8番目の注文である場合、それは出荷2などです。

これはで行うことができますSQL Serverか?そうでない場合、私はこれを何に書くべきですか?そして、for-loop私はこの場合に何を使うべきですか?

編集:これが私が取得しようとしている出力です。4番目の製品が出荷された後、注文を再開する必要があることに注意してください(つまり、6つの製品が2つの出荷[4つの製品と2つの製品]に分割され、9つの製品が3つの出荷[4、4、および1]に分割されます。

PRODUCTSSHIPPED SALESDATE   SALESTIME   CUSTOMERID  PRODUCTCOST SHIPPINGCOST
4               6/12/12         1005    T891002     672.8       10.95
1               6/12/12         1005    T891002     99.99       7.95
2               6/12/12         1010    X637251     1524.94     8.95
1               6/12/12         1017    T512AT0     49.95       7.95
1               6/12/12         959     7661X0A     99.99       7.95
4

4 に答える 4

2

このステートメントから、あなたはこれが欲しいようです:

私が判断しようとしているのは、注文ごとに出荷される製品の数と、製品のコストと送料の合計です。

http://sqlfiddle.com/#!3/e0e71/30

foreach ループを使用する意味がわかりません。

アップデート:

サブクエリとシーリング関数を使用して動作するようにしました

フィドルを更新しました

参考までに SQL は次のとおりです。

SELECT
SalesDate,
SalesTime,
CustomerID,
SUM(ProductCost),
SUM(ShippingCost)
FROM 

(
SELECT
       SalesDate,
       SalesTime,
       CustomerID,
       ProductCost,
       ShippingCost,
       ROW_NUMBER() OVER (PARTITION BY salesdate, salestime, customerid ORDER BY CustomerID) as ProdNumber
FROM Orders
) as Summary
group by SalesDate, SalesTime, CustomerID, ceiling(ProdNumber / 4.0)

ROW_NUMBER を使用して各注文の現在の製品数を取得し、これをサブクエリにして、グループ化できるようにしました。グループ化では、製品の数を 4 で割った値を (float として) 使用し、天井関数を使用して最も近い int に切り上げ、4 つにグループ化します。

于 2012-06-11T17:03:05.500 に答える
1

これにより、その顧客/日付/時刻の注文数が NumOrders フィールドに表示されます。これは、私の新しいお気に入りの関数である Row_Number を使用しています。

SELECT [CUSTOMERID], [SALESDATE], [SALESTIME], MAX(NumOrders)
FROM (
    SELECT [CUSTOMERID], 
    [SALESDATE],
    [SALESTIME],
    ROW_NUMBER() OVER(PARTITION BY [CUSTOMERID], [SALESDATE], [SALESTIME] ORDER BY [CUSTOMERID]) AS NumOrders
) t1
GROUP BY [CUSTOMERID], [SALESDATE], [SALESTIME]
于 2012-06-11T16:55:53.187 に答える
1

ここでループが必要だとは思わない。完全に避けられない場合を除き、通常、SQLでは悪い習慣と見なされます。ユーザーが同じ日時に注文した場合、それは同じ論理注文 (注文グループ) に属していると思いますか? とにかく、問題全体はおそらく SQL サーバーのpartition と over 句を使用して解決できます。そこのサンプル D を見てください。必要なものに近いことをしていると思います。

編集
範囲句はSQL 2012でのみ使用できますが、引き続きパーティショニングと行番号を使用し、返された行番号で単純な計算(ROWNUMBER / 4)を使用して結果をグループ化できます

于 2012-06-11T16:56:27.413 に答える
0

ループが必要な理由がまったくわかりません..

Select count(*) as ProductsOnOrder, LEFT(CustomerID,4), as CID,
       SalesDate, SalesTime, sum(productCost), sum(ShippingCost)
FROM YOUR_TABLENAME
GROUP BY left(CustomerID,4), salesdate, salestime

どの注文番号を表示しますか? ミン?マックス?全員?何?製品に関する同じ質問 製品をリストしますか、それとも単に数えますか?

Select count(*) as ProductsOnOrder, LEFT(CustomerID,4), as CID,
       SalesDate, SalesTime, sum(productCost), sum(ShippingCost),
       min(orderID), Max(orderID)
FROM YOUR_TABLENAME
GROUP BY left(CustomerID,4), salesdate, salestime

orderID が注文の各行で連続していることはわかっているので、最小値/最大値を返し、その 2 つを減算してカウントを取得することもできます。

于 2012-06-11T16:55:22.750 に答える