回答

收藏

查询以显示交易表中的已用积分

技术问答 技术问答 234 人阅读 | 0 人回复 | 2023-09-14

我正在使用一个表,其中包含信贷交易,我想在其中显示销售时花费了谁的信贷。
, s1 G3 e7 D2 H1 C/ `在表中:
& E4 S; \) h8 C, O9 q( W2 r; c- eCredits由实体使用唯一的实体代码添加(记录在列中GivenByUserCode)* B: n. |1 `& e/ o3 P3 x
信用额添加始终具有这样的代码。# }6 H# O* c# a) I
花费的信用额始终为负值。' ?* e3 `: x5 C9 P( H% _
那些花学分会不会有一个实体的代码(价值GivenByUserCodeIS null)。
$ d; w( V: V' @* R
8 u5 H' n" Z8 x* O1 T2 j; v6 N4 b
以上述数据为例,如果用户2018-01-02在报表上进行了购买,则应显示所有源自的信用BM01。加法的复杂性在于,一个购买可以分为多个加法,请参见将购买2018-02-03分为三个加法。6 _2 u+ d' k  e
我认为该解决方案与使用cte及以上有关,但我没有使用这些经验。我确实在SqlServerCentral上发现了类似(不同)的问题。7 L# Y: R0 H+ \& b+ h
任何帮助/方向将不胜感激。
( R" L  Z; |& F9 [3 _% ^
( D5 H/ e( J/ j0 m4 V# ~8 j! w* m输入和DDL
/ Y( i$ \5 Y9 O$ }* p/ g- gDECLARE @CreditLogs TABLE(CreditLogId int not null identity(1,1), Credits INT NOT NULL, OccurredOn DATETIME2(7) NOT NULL, GivenByUserCode VARCHAR(100) NULL)- [8 v# ~. ]" L" a8 m9 w% M
INSERT INTO @CreditLogs (Credits, OccurredOn, GivenByUserCode) VALUES
; @4 _" e/ n" [/ v- k3 K5 C% V  (10,  '2018-01-01', 'BM01'); p# q  a, u+ }7 o
, (10,  '2018-01-01', 'BM01')
" E/ ~8 V# {2 y/ B( y' A, (-10, '2018-01-02', NULL)
( ~: v- d" W( f/ _, E, (-5,  '2018-01-04', NULL)
1 h; E/ ]& f! ?4 S7 p, (5,   '2018-02-01', 'SP99')
+ n. e) l5 M# l% ]; k, (40,  '2018-02-02', 'BM02')
- i: j) W5 w7 ]0 d( I, (-40, '2018-02-03', NULL)
. l7 P' z" [) x9 {! y, F. F, (-4,  '2018-03-05', NULL)
' U0 }' |/ @" J4 b% r' \& d以表格形式输入
! L: Z: G1 Z! sCreditLogId | Credits | OccurredOn | GivenByUserCode- W# z  F4 |4 W3 j8 g8 I/ E
------------+---------+------------+----------------* c7 M0 Q$ }! m5 p4 X0 a* {
          1 |      10 | 2018-01-01 |            BM01" w9 @- O4 u. Z% k, A/ ?5 i
          2 |      10 | 2018-01-01 |            BM01
+ N6 t+ ]' q7 X) c7 j          3 |     -10 | 2018-01-02 |            NULL
0 c( g6 G, ]. _3 t5 ~2 w0 M          4 |      -5 | 2018-01-04 |            NULL! Y* l0 x5 H* _% E( z" r
          5 |       5 | 2018-02-01 |            SP99/ a3 ^8 [! w( o# S; w# b: e9 Q5 s
          6 |      40 | 2018-02-02 |            BM02
2 K1 C& T% Y! |4 j2 K, }          7 |     -40 | 2018-02-03 |            NULL
0 m5 c; `) d2 W: z" v          8 |      -4 | 2018-03-05 |            NULL
1 `& c9 G4 B* U* r预期产量; h2 G, {3 ?4 {6 M! F6 H
SELECT *9 e! J7 j9 f7 ?+ `7 D  X
FROM (VALUES
. f0 l! \5 ^  B1 N$ x! |9 R# v. d. |     (3, '2018-01-02', 10, 'BM01')7 `2 q& c! F  e; c
    ,(4, '2018-01-04', 5, 'BM01')( g0 l- q. ~) i% _
    ,(7, '2018-02-03', 5, 'BM01')2 V3 B$ D0 [; t3 D3 J2 k/ W# N9 B
    ,(7, '2018-02-03', 5, 'SP99')
) s% u. `3 w5 v  P# t    ,(7, '2018-02-03', 30, 'BM02')
2 C" `* S; z2 C3 Y( g7 u* F    ,(8, '2018-03-05', 4, 'BM02')
. C4 p: s  S3 j$ `3 Z5 j2 Y# c1 U# B) expectedOut (CreditLogId, OccurredOn, Credits, GivenByUserCode)# _; y& c+ [, c! j
产生输出
8 Y" _* M; F2 \$ qCreditLogId | Occurred on | Credits | GivenByUserCode1 e5 T( k( Y/ A0 [
------------+-------------+---------+----------------
% U  D1 s' d( ]. [7 Q" l' Z          3 |  2018-01-02 |      10 |            BM01* U. C( f: N. O8 _1 l/ b
          4 |  2018-01-04 |       5 |            BM016 [$ g- }# i& l
          7 |  2018-02-03 |       5 |            BM01
- [  z& k1 _& w  _( c  p1 m) {% r          7 |  2018-02-03 |       5 |            SP99
) h$ k" g6 Z7 E' e          7 |  2018-02-03 |      30 |            BM02! L, n6 Q0 |/ [* |- _
          8 |  2018-03-05 |       4 |            BM02$ M9 {/ R" e  X% ?! I$ d  ?
到目前为止的代码
1 D- K7 w9 |0 K) A  Y0 t6 @数量不多,我不确定从这儿去哪里。
+ M( W1 N/ X8 I3 _1 P% G! u' WWITH totals AS (0 P7 c1 k! B; o2 M
    SELECT CreditLogId, OccurredOn, credits, sum(credits) OVER(ORDER BY OccurredOn) AS TotalSpent
) o. _  U- F. _/ B    FROM @CreditLogs
4 O" k1 W+ H8 I1 I  |4 x9 k    WHERE Credits 2 w: c5 ~+ c% h% z" ^6 T
附加说明# B9 G3 [3 z& w  a; M$ W% d' n" K: A
预期输出是来自这些信用额度的每个已花费信用额度。贷项以先进先出(FIFO)的基础花费。在此,对示例输出中的每个值进行说明,以期阐明所需的输出。
, X9 l6 l8 n% M# e对于10个信用额度的消费(信用记录ID 3),可以追溯到信用记录ID 1的增加值5 _$ I* F( Q9 x% v0 e7 m- {
对于5个信用额度的消费(信用记录ID 4),可以追溯到信用记录ID 2(由于信用记录ID 1被“用完”)而增加。
' \; b! x! x& |# D9 _$ R  @6 n; p对于信用记录ID为7的40个信用额度的支出,可以追溯到
) g" p" E6 |0 O6 @信用记录ID 2、5学分中的剩余余额
+ L1 N  d% K0 |+ ?. ]7 c/ a信用记录ID 5(加5)
/ C" ]. ^+ K% O- R: N信用记录ID 6(又加上了40个余额,所以还剩下10个)1 [3 C; M- v0 I
对于在信用记录8中花费4信用,将使用信用记录ID 6的余额3 g9 P% N4 P" m: `- W1 r6 ]

, V  J: ]/ [3 i1 b# p2 Q2 v5 ?$ p请注意,总余额仍为6个学分,余额不必为零,但永远不会为负数,因为用户只能花费他们所拥有的。9 i6 B7 ^) s, @3 m1 I' Z8 d, T6 P
               
( A% D* W7 a% r+ m解决方案:$ _9 W& @' n$ k* y
                3 o+ V) ]/ J8 s0 n

! J0 c/ v, F& s( }% w4 \3 W% v5 B5 r' W: H
                试试这个:
3 L$ B( N5 A2 R* D) SWITH Credits_added AS (' \9 i& K" k% \: Y0 P- [; ]
    SELECT CreditLogId, OccurredOn, credits
4 }* ~  N1 t% j1 Z; \: ~& ~: A    , SUM(credits) OVER (ORDER BY CreditLogId) - credits AS b --before
, g. m9 d0 a+ B' Y6 T, M0 |    , SUM(credits) OVER (ORDER BY CreditLogId) AS a --after4 ]. B- }+ _/ H* ]6 {
    , GivenByUserCode
$ J+ L8 {2 s  x: D& q# x    FROM @CreditLogs
# W# ^" c* ?2 ^    WHERE Credits > 0)) E5 a1 ?# h1 q  f4 D0 Z/ @
, Credits_spent AS (# L; ^- c. P' }$ g
    SELECT CreditLogId, OccurredOn, credits
7 |0 o' P# d0 P9 Q- G- A8 a0 u    , SUM(credits) OVER (ORDER BY CreditLogId) * -1 + credits AS b: ]/ x7 W7 ]' l- O! D0 G$ H
    , SUM(credits) OVER (ORDER BY CreditLogId) * -1 AS a
  |: o* W+ h& I/ F; F/ i% o    FROM @CreditLogs3 D' A+ c! ^8 [! s, Z; K5 x
    WHERE Credits  s.a THEN s.a ELSE a.a END - CASE WHEN a.b > s.b THEN a.b ELSE s.b END AS Credits 8 }) I+ @& M- @+ d( o
, a.GivenByUserCode8 M% _5 I$ N9 u& H" Z' B
FROM Credits_added AS a
$ l% b  ?5 G  w! C& z  ]INNER JOIN Credits_spent AS s ON a.a > s.b AND s.a > a.b
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则