Vasquez155
Aktiver Benutzer
- Beiträge
- 29
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
WITH t(periode_beginn) AS (
SELECT dateadd(month,datediff(month,0,getdate()),0)
UNION ALL
SELECT dateadd(month,-1,periode_beginn)
FROM t
WHERE dateadd(month,-1,periode_beginn) >= dateadd(year,-2,getdate())
), basis AS (
SELECT sum(erlöse) AS sum_erloese, Kunde, a.land_id,
periode_beginn,
right('0' + cast(datepart(month,periode_beginn) AS VARCHAR(6)),2) +
cast(datepart(year,periode_beginn) AS VARCHAR(6)) AS periode
FROM t
CROSS JOIN ( SELECT DISTINCT kunde.id,kunde.kunde FROM kunde INNER JOIN auftrag ON kunde.id = auftrag.kunde_id WHERE auftrag.datum >= dateadd(year,-2,getdate()) ) k
CROSS JOIN ( SELECT DISTINCT auftrag.kunde_id,auftrag.land_id FROM auftrag ) l
left outer join datum d on
d.Monat_Jahr = right('0' + cast(datepart(month,periode_beginn) AS VARCHAR(6)),2) +
cast(datepart(year,periode_beginn) AS VARCHAR(6))
left join auftrag a
on a.datum_id = d.id
and a.kunde_id = k.id
and a.land_id = l.land_id
group by
right('0' + cast(datepart(month,periode_beginn) AS VARCHAR(6)),2) +
cast(datepart(year,periode_beginn) AS VARCHAR(6)), kunde, a.land_id
), basis_mit laufendem_umsatz AS (
SELECT *,
sum(CASE WHEN periode_beginn BETWEEN dateadd(month,-24,getdate()) AND getdate() THEN umsatz ELSE NULL END) OVER (PARTITION BY kunde,land ORDER BY periode_beginn) AS laufender_umsatz_der_letzten_2jahre,
(CASE WHEN periode_beginn BETWEEN dateadd(month,-24,getdate()) AND getdate() THEN 1 ELSE 0 END) AS hat_umsatz
FROM basis
)
SELECT *,
(CASE WHEN hat_umsatz = 1 AND lag(hat_umsatz) OVER (PARTITION BY kunde,land ORDER BY periode_beginn) = 0 THEN 'Neukunde' WHEN hat_umsatz = 1 THEN 'Kunde' ELSE NULL END) AS status_kunde
FROM basis_mit laufendem_umsatz
Nein so gar nicht weil ich den eigentlichen Code komplett verdrängt habe, weshalb ich auch glücklich war das es "läuft"Besser verständlich?
Das hat mich gestern verzweifeln lassen aber das war auch spät Abends jetzt klapptsDie ersten zwei Spalten habe ich, die dritte soll als neue Spalte per SQL dazukommen
Monat Umsatz norm_ letzter Umsatz
012023 120
022023 0 120
032023 130 120
032023 110 130
042023 120 110
052023 0 120
062023 0 120
072023 100 120
Eigentlich ist es immer der Umsatz vom Vormonat, allerdings wenn ich gar keinen Umsatz in Monaten generiere, soll der letzte normale Umsatz in das Feld norm_Letzter Umsatz geschrieben werden, der im Beispiel 072023 nicht im Monat 062023 liegt, sondern in 042023.
WITH tabelle (Monat,Umsatz,[norm_ letzter Umsatz]) AS (
SELECT '012023',120,NULL UNION ALL
SELECT '022023',0,120 UNION ALL
SELECT '032023',130,120 UNION ALL
SELECT '032023',110,130 UNION ALL
SELECT '042023',120,110 UNION ALL
SELECT '052023',0,120 UNION ALL
SELECT '062023',0,120 UNION ALL
SELECT '072023',100,120
)
SELECT t2.*,
lag(t2.Umsatz,t2.offset) OVER (ORDER BY t2.rownumber) AS gesuchter_wert
FROM (
SELECT t1.*,
1 + sum(t1.addoffset) OVER (ORDER BY t1.rownumber) AS offset
FROM (
SELECT t0.*,
( CASE
WHEN lag(t0.Umsatz) OVER (ORDER BY t0.rownumber) = 0
THEN 1
WHEN lag(t0.Umsatz,2) OVER (ORDER BY t0.rownumber) = 0
AND lag(t0.Umsatz) OVER (ORDER BY t0.rownumber) > 0
THEN -1
ELSE 0
END ) AS addoffset
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY tabelle.Monat,tabelle.Umsatz DESC) AS rownumber,
tabelle.*
FROM tabelle
) t0
) t1
) t2
ORDER BY t2.rownumber
Kunde | Region | Umsatz | norm. Umsatz | Monat |
40 | 1 | 369.31 | 202302 | |
40 | 1 | 630.46 | 369.31 | 202303 |
40 | 1 | 50.00 | 630.46 | 202304 |
40 | 1 | 383.35 | 630.46 | 202305 |
40 | 1 | 292.40 | 383.35 | 202306 |
40 | 1 | 0.00 | 292.40 | 202307 |
40 | 1 | 0.00 | 292.40 | 202308 |
40 | 1 | 0.00 | 292.40 | 202309 |
40 | 1 | 103.04 | 292.40 | 202310 |
Ähm, ich bin nicht sicher. Willst du wirklich, das der Umsatz von Vormat genommen wird, abhängig davon, ob er kleiner als 10% des norm_Umsatz vom Vormonat (norm_Umsatz von Vormonat entspricht dem Umsatz des Vorvormonats) ist? Also du würdest dann den Umsatz vom Vormonat mit einem Wert vergleichen, den du erst noch ermitteln willst. Einem Wert, den du z.B. erst im dritten Monat haben kannst.Übernehme in Spalte norm_Umsatz
- den Wert vom letzten Umsatz vom Vormonat ausser, er ist kleiner als 10% vom ermittelten norm_Umsatz vom Vormonat (siehe Zeile 3 und 4)
jetzt die 369.31 oder die 630.46 meinst, bleibt das Problem das du das nicht mit Window-Funktionen schaffen kannst. Du willst mit einem Wert vergleichen, der noch nicht bekannt ist. Wenn überhaupt geht das mit CTE.norm_Umsatz vom Vormonat
Das sollte eigentlich bereits funktionieren, da ich auf Umsatz = 0 prüfe.- Wenn es im Monat keinen Umsatz gegeben hat, nimm den letzten Umsatz, der zuletzt in einem Monat generiert wurde (siehe Zeile 7 und 8)
WITH tabelle(kunde,region,umsatz,norm_umsatz_zielwert,monat) AS (
SELECT 40,1,369.31,NULL,202302 UNION ALL
SELECT 40,1,630.46,369.31,202303 UNION ALL
SELECT 40,1,50.00,630.46,202304 UNION ALL
SELECT 40,1,383.35,630.46,202305 UNION ALL
SELECT 40,1,292.40,383.35,202306 UNION ALL
SELECT 40,1,0.00,292.40,202307 UNION ALL
SELECT 40,1,0.00,292.40,202308 UNION ALL
SELECT 40,1,0.00,292.40,202309 UNION ALL
SELECT 40,1,103.04,292.40,202310
), t0 AS (
SELECT ROW_NUMBER() OVER (PARTITION BY tabelle.kunde,tabelle.region ORDER BY tabelle.monat) AS rownumber,
tabelle.*
FROM tabelle
), t1 AS (
SELECT t0.kunde,
t0.region,
t0.umsatz,
t0.norm_umsatz_zielwert,
t0.monat,
t0.rownumber,
cast(NULL AS MONEY) AS lag1_umsatz,
cast(NULL AS MONEY) AS lag2_umsatz,
cast(NULL AS MONEY) AS norm_umsatz
FROM t0
WHERE t0.rownumber = 1
UNION ALL
SELECT t0.kunde,
t0.region,
t0.umsatz,
t0.norm_umsatz_zielwert,
t0.monat,
t0.rownumber,
cast(t1.umsatz AS MONEY) AS lag1_umsatz,
(CASE WHEN t1.rownumber = 1 THEN NULL ELSE t1.lag1_umsatz END) AS lag2_umsatz,
( CASE
WHEN t1.umsatz IS NOT NULL
AND t1.rownumber > 1
THEN ( CASE
WHEN cast(t1.umsatz AS MONEY) > cast(t1.norm_umsatz AS MONEY) * 0.1
THEN cast(t1.umsatz AS MONEY)
ELSE cast(t1.norm_umsatz AS MONEY)
END )
WHEN t1.umsatz IS NOT NULL
AND t1.rownumber = 1
THEN cast(t1.umsatz AS MONEY)
ELSE NULL
END ) AS norm_umsatz
FROM t1
INNER JOIN t0
ON t1.kunde = t0.kunde
AND t1.region = t0.region
AND t1.rownumber + 1 = t0.rownumber
)
SELECT *
FROM t1
WITH tabelle(kunde,region,umsatz,norm_umsatz_zielwert,monat) AS (
SELECT 40,1,369.31,NULL,202302 UNION ALL
SELECT 40,1,630.46,369.31,202303 UNION ALL
SELECT 40,1,50.00,630.46,202304 UNION ALL
SELECT 40,1,383.35,630.46,202305 UNION ALL
SELECT 40,1,292.40,383.35,202306 UNION ALL
SELECT 40,1,0.00,292.40,202307 UNION ALL
SELECT 40,1,0.00,292.40,202308 UNION ALL
SELECT 40,1,0.00,292.40,202309 UNION ALL
SELECT 40,1,103.04,292.40,202310
), t0 AS (
SELECT ROW_NUMBER() OVER (PARTITION BY tabelle.kunde,tabelle.region ORDER BY tabelle.monat) AS rownumber,
tabelle.*
FROM tabelle
), t1 AS (
SELECT t0.kunde,
t0.region,
t0.umsatz,
t0.norm_umsatz_zielwert,
t0.monat,
t0.rownumber,
cast(NULL AS MONEY) AS lag_umsatz,
cast(NULL AS MONEY) AS norm_umsatz
FROM t0
WHERE t0.rownumber = 1
UNION ALL
SELECT t0.kunde,
t0.region,
t0.umsatz,
t0.norm_umsatz_zielwert,
t0.monat,
t0.rownumber,
cast(t1.umsatz AS MONEY) AS lag_umsatz,
( CASE
WHEN t1.umsatz IS NOT NULL
AND t1.rownumber > 1
THEN ( CASE
WHEN cast(t1.umsatz AS MONEY) > cast(t1.norm_umsatz AS MONEY) * 0.1
THEN cast(t1.umsatz AS MONEY)
ELSE cast(t1.norm_umsatz AS MONEY)
END )
WHEN t1.umsatz IS NOT NULL
AND t1.rownumber = 1
THEN cast(t1.umsatz AS MONEY)
ELSE NULL
END ) AS norm_umsatz
FROM t1
INNER JOIN t0
ON t1.kunde = t0.kunde
AND t1.region = t0.region
AND t1.rownumber + 1 = t0.rownumber
)
SELECT *
FROM t1