SQL fejtörő 11.

Feladat: van egy trading accountunk, ezen hol nyerünk, hol vesztünk. Az account nem mehet 0 alá, de ha nagyobb a veszteségünk mint az account értéke, a broker behajtja rajtunk a veszteséget, vissza kell pótolni a pénzt. A feladat számla mozgásainak összegzése.

Az elvárt kimenet az SQL tartalomban látható.

USE tempdb;

IF OBJECT_ID(N'dbo.Trades', N'U') IS NOT NULL DROP TABLE dbo.Trades;

CREATE TABLE dbo.Trades
(
  tradeId INT NOT NULL PRIMARY KEY,
  amount  INT NOT NULL
);

INSERT INTO dbo.Trades(tradeId, amount)
   values (1,12),(2,-25),(3,40),(4,10),(5,-23),(6,-32),(7,14),(8,-23),(9,12),(10,-20),(11,13),(12,-90);
GO

--Elvárt kimenet:
--tradeId	amount	accountValue	moneyBack
--1	12	12	0
--2	-25	0	13
--3	40	40	0
--4	10	50	0
--5	-23	27	0
--6	-32	0	5
--7	14	14	0
--8	-23	0	9
--9	12	12	0
--10	-20	0	8
--11	13	13	0
--12	-90	0	77

A megfejtéseket szokás szerint kommentben várom, amelyeket 4 nap múlva engedek ki.

A Test Driven Development tanfolyam következő felvonása április 20-án lesz, jövő hét szerdáig még 25% kedvezménnyel lehet jelentkezni!

2 Responses to “SQL fejtörő 11.”

  1. Laci Says:

    ;WITH x AS
    (
    SELECT tradeid, amount, amount as accountValue, 0 as moneyBack
    FROM dbo.Trades
    WHERE tradeid=1
    UNION ALL
    SELECT y.tradeid, y.amount, iif(x.accountValue + y.amount<0,0,x.accountValue + y.amount), -1*iif(x.accountValue + y.amount<0,x.accountValue + y.amount,0)
    FROM x INNER JOIN dbo.Trades AS y
    ON y.tradeid = x.tradeid+1
    )
    SELECT *
    FROM x

  2. Pócza Krisztián Says:

    Első körben egy ilyen ugrott be:
    +++
    with tradeaccount as
    (
    select
    tradeid,
    amount,
    case when amount > 0 then amount else 0 end as accountValue,
    case when amount >= 0 then 0 else -amount end as moneyBack
    from Trades
    where tradeid = 1
    union all
    select t.tradeid,
    t.amount,
    case when t.amount + a.accountValue > 0 then t.amount + a.accountValue else 0 end as accountValue,
    case when t.amount + a.accountValue >= 0 then 0 else -(t.amount + a.accountValue) end as moneyBack
    from Trades as t
    inner join tradeaccount a on (a.tradeid = t.tradeid – 1)
    )
    select * from tradeaccount
    +++

    MAXRECURSION optionnel lehet a megengedett recurziók számát növelni.
    Ha ezt is túllépnénk, akkor pl. többször lehet a fenti recursive CTE-t egymás után futtatni úgy, hogy a rákövetkezőt mindig a megelőző végeredményével inicializáljuk.

    Lehet opció még cursor-os megoldás, de annak még több baja lehet, mint egy recursive CTE-snek.