ケース
こんにちは、私は顧客ロイヤルティシステムを構築しています。このシステムでは、顧客は個人のロイヤルティカードを使用してポイントを獲得し、このポイントで商品を購入できます。一般的に、私たちは3つの当事者を扱います。
- ロイヤルティプロバイダー(システム全体のキャッシュフローを管理します)
- ショップ(-owners / -employees)(顧客にポイントを販売または譲渡したり、顧客からポイントを取得したりできます)
- 顧客(ポイントを獲得または購入できる/獲得または購入したポイントで製品を購入できる)
プロバイダーは毎週、オープントランザクションに基づいて指定された期間、ショップごとに請求書を生成する必要があります。
100ポイントは€1、-に等しいので、基本的にすべてのユーロセント(€0.01)は私たちのシステムでは1ポイントです。
たとえば、店員が10ユーロ(1000ポイント)のポイントを顧客に販売すると、次のトランザクションが生成されます。
| RecordId | Description | Credit | Debit | State | CreationDate ... CardId | LocationId | InvoiceId |
| (ID) | (Descr.) | 1000 | 0 | Open | ... | 10001 | NULL |
今、顧客は€3の製品を購入します-。これにより、次のトランザクションが生成されます。
| RecordId | Description | Credit | Debit | State | CreationDate ... CardId | LocationId | InvoiceId |
| (ID) | (Descr.) | 0 | 300 | Open | ... | 10001 | NULL |
その週の後半に、同じ顧客が同じ店で別の製品を2ユーロで購入します。これにより、次のトランザクションが生成されます。
| RecordId | Description | Credit | Debit | State | CreationDate ... CardId | LocationId | InvoiceId |
| (ID) | (Descr.) | 0 | 200 | Open | ... | 10001 | NULL |
別のクライアントが€25、-ポイント(2500ポイント)を購入します。これにより、次のトランザクションが生成されます。
| RecordId | Description | Credit | Debit | State | CreationDate ... CardId | LocationId | InvoiceId |
| (ID) | (Descr.) | 2500 | 0 | Open | ... | 10001 | NULL |
この顧客は€4の製品を購入します-(400ポイント)これにより、次のトランザクションが生成されます。
| RecordId | Description | Credit | Debit | State | CreationDate ... CardId | LocationId | InvoiceId |
| (ID) | (Descr.) | 0 | 400 | Open | ... | 10001 | NULL |
したがって、ショップの所有者は、プロバイダーに(1000-(300 + 200)= 500)+((2500-400)-2100)=26ユーロを支払う必要があります。
請求
ショップの従業員は、週末に次のデータが記載された請求書を受け取る必要があります
Period Invoice - Week X
Period Start: dd-mm-yyyy
Period End: dd-mm-yyyy
Points sold: 3500
Points collected: 900
------------------------ -
Total: 2600
To pay: € 26,-
店主がお金しかもらえない場合もありますが、その場合は請求書がマイナスになります。
データベース
さて、私はこのクエリに必要なテーブルだけを説明します。
請求書
[RecordId] [int] IDENTITY(10001,1) NOT NULL,
[Description] [varchar](50) NULL,
[ToPay] [int] NOT NULL,
[ToReceive] [int] NOT NULL,
[Total] [int] NOT NULL,
[PeriodStart] [datetime] NOT NULL,
[PeriodEnd] [datetime] NOT NULL,
[State] [varchar](10) NOT NULL,
[PaidDate] [datetime] NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[DeletedDate] [datetime] NULL,
[LocationId] [int] NOT NULL
トランザクション
[RecordId] [int] IDENTITY(10001,1) NOT NULL,
[Description] [varchar](50) NOT NULL,
[Credit] [int] NOT NULL,
[Debit] [int] NOT NULL,
[State] [varchar](10) NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[DeletedDate] [datetime] NULL,
[CustomerId] [int] NOT NULL,
[EmployeeId] [int] NOT NULL,
[CardId] [int] NOT NULL,
[LocationId] [int] NOT NULL,
[InvoiceId] [int] NOT NULL
クエリ(これまでのところ)
特定の期間に開いているすべてのトランザクションを取得するために、ストアドプロシージャを作成(ええと、コピー)できましたか?
INSERT INTO [Invoices] ([Description], [ToPay], [ToReceive], [Total], [PeriodStart], [PeriodEnd], [LocationId])
SELECT
@Description AS [Description],
SUM([Credit]) AS [ToPay],
SUM([Debit]) AS [ToReceive],
SUM([Credit]) - SUM([Debit]) AS [Total],
@PeriodStart AS [PeriodStart],
@PeriodEnd AS [PeriodEnd],
[LocationId]
FROM
[Transactions]
WHERE
[State] = 'Open' AND
[CreatedDate] BETWEEN @PeriodStart AND @PeriodEnd
GROUP BY [LocationId]
選択すると、次の結果が得られます。
| ToPay | ToReceive | Total | PeriodStart | PeriodEnd | LocationId |
| 3500 | 900 | 2600 | (Start) | (End) | 10001 |
そして、[請求書]テーブルに挿入されます。
質問
上記のクエリを使用することにより、すべての場所(ショップ)は、指定された期間の独自のレコードを取得します。したがって、すべての場所が[Invoices]テーブルの請求書レコードを取得します。
[RecordId]列は、挿入(ID)ごとに1つずつ増加します
これは私が立ち往生しているところです:すべてのレコード作成後、その[RecordID]は[Invoices]テーブルで新しいレコードを生成するために使用されるレコードの[Transactions]テーブル([InvoiceId]列)に書き込まれる必要があります、トランザクションの[State]列も「Open」から「Invoice」に変更する必要があります
最新のレコードのRecordidを取得する機能を知っています
SCOPE_IDENTITY();
誰かがこれを行う方法を教えてもらえますか?
結果(あるべき姿)
ショップの所有者が請求書の詳細を要求した場合、InvoiceIdですべてのトランザクションを選択することでトランザクションを解決できます。
SELECT * FROM [Transactions] WHERE [InvoiceId] = @InvoiceId
追加情報
システムはMSSQL2008を実行しており、フロントエンドはMS MVC3(C#)を実行しています。
更新:データモデルを少し変更する必要がありました。
私の(それほどグーグーではない)英語のためのPS謝罪。
アップデート
OK、追加して修正しました
UPDATE [Transactions] SET
[Transactions].[State] = 'Invoice',
[Transactions].[InvoiceId] = [Invoices].[RecordId]
FROM
[Transactions]
INNER JOIN
[Invoices]
ON
[Transactions].[CreatedDate] BETWEEN @PeriodStart AND @PeriodEnd
しかし、これは単なるハックであり、これを行う方法ではないと思います。これが正しくないと思う理由は、2つのクエリ間でテーブルに変更を加えることができるか(トランザクションが追加されたとしましょう)?これらは両方とも同じストアドプロシージャにあります。今のところ、これは問題ありません。ショップが閉まっている深夜にトランザクションが解析されるためです。