2016-09-27 8 views
0

geändert hat habe ich eine Rep-Tabelle mit den folgenden Feldern:TSQL - Wählen Sie Zeilen, in denen Spaltenwert

enter image description here

Es kann die RepNbr seiner Änderungen. Ich muss eine Abfrage schreiben, die zeigt, was die repnbr für jedes effektive Datum war. Was das Repnbr war vorher und dann, wenn es eine Veränderung gibt. Also, ich versuche, das Repnbr von M258 am 21.10. (Was das Repnrbr vorher war), das RepNBR von DM25 am 6.3.16 und was das RepNbr von M258 am 6.8.16 war.

Ich habe die folgende Abfrage versucht: Diese Abfrage zieht nur das Effektivdatum von 6/3 und 6/8 und schaut nicht zurück, was der repnbr zuvor war.

;with t1 as 
(
select 
    acctnbr, 
    repnbr, 
    effectivedate, 
    rn = row_number() over (partition by repnbr order by acctnbr) 
from 
    reptable 
where 
    acctnbr = '123' 
) 
select 
    * 
from 
    t1 
where 
    rn = '1' 
order by 
    effectivedate 

Ergebnisse:

enter image description here

Meine Ausgabe aussehen sollte:

enter image description here

Was bin ich mit meiner Frage zu tun falsch? Danke,

+0

wie sollte die Ausgabe aussehen? –

+0

'Ich versuche, die repnbr von M258 auf 10/21 zu ziehen' - Ich finde keinen Hinweis darauf in Ihrem Code – techspider

+0

alles, was Sie getan haben, ist eine Reihe von Daten auszuschließen ... und Sie werden zu Sie möchten nach Acct, EffectiveDate partitionieren, damit Sie für jedes Konto für jeden Gültigkeitszeitraum einen Datensatz erhalten. Da Ihre Zeilen sowieso einzigartig sind, scheint das alles trivial zu sein. Vielleicht würde Ihr realer Datensatz ein besseres Beispiel zeigen. – scsimon

Antwort

1

USE LAG() und oder LEAD() Funktionen für SQL 2012+

DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-10-15') 
,(123,'M258','2015-10-21') 
,(123,'DM25','2015-06-03') 
,(123,'M258','2015-06-08') 

;WITH cte AS (
    SELECT * 
     ,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr 
    FROM 
     @Rep 
) 

SELECT Acct, RepNbr, EffectiveDate 
FROM 
    cte 
WHERE 
    PrevRepNbr IS NULL 
    OR PrevRepNbr <> RepNbr 

Beachten Sie aber, dass Ihr Beispiel nicht in der Reihenfolge der Zeitpunkt des Inkrafttretens ist so Ihre Ergebnisse werden nicht, wie Sie beschrieben. Weil 10-21 ist nach 6-3 ...

Acct RepNbr EffectiveDate 
123  DM25 2015-06-03 00:00:00.000 
123  M258 2015-06-08 00:00:00.000 
123  M258 2015-10-15 00:00:00.000 
123  M258 2015-10-21 00:00:00.000 

So das würde bedeuten, dass die RepNbr ändert sich nur auf 6/8 von DM25 bis M258

Wenn Sie Ihre Beispieltabelle ändern:

DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-06-03') 
,(123,'M258','2015-06-08') 
,(123,'DM25','2015-10-15') 
,(123,'M258','2015-10-21') 

Dann würde es mit M258 am 6/3 anfangen, am 10/15 zu DM25 wechseln und dann am 10/21 zurück zu M258 wechseln.

Wenn Sie nicht möchten, dass das Original/Startwert sehen, die ohne @Rep WHERE PrevRepNbr IS NULL

bearbeiten entfernen:

;WITH cte AS (
    SELECT 
     Acct 
     ,RepNbr 
     ,EffectiveDate 
     ,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr 
    FROM 
     TableName 
) 

SELECT Acct, RepNbr, EffectiveDate 
FROM 
    cte 
WHERE 
    PrevRepNbr IS NULL 
    OR PrevRepNbr <> RepNbr 
+0

Das funktioniert, außer dass ich über 600.000 Konten habe, um eine Insert in @Rep durchzuführen. Gibt es eine Möglichkeit, die Daten ohne INSERT INTO zu ziehen? Ich zeige nur ein Beispiel. – BIReportGuy

+0

yeah nur ersetzen FROM @Rep mit FROM Tabellenname Ihrer ursprünglichen Tabelle und nicht die Tabelle Variable überhaupt verwenden – Matt

+0

@BIGuy, wenn meine Antwort für Sie arbeitete, ziehen Sie bitte in Betracht, es zu akzeptieren, damit andere Sie wissen, was Sie benötigten und Reputationspunkte zugewiesen bekommen. Vielen Dank. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Matt

1

Ältere Versionen von SQL trennen Gruppierung

DECLARE @Rep AS TABLE (Acctnbr int, RepNbr CHAR(4), EffectiveDate DATETIME) 
INSERT INTO @Rep VALUES 
(123,'M258','2015-10-15') 
,(123,'M258','2015-10-21') 
,(123,'DM25','2015-06-08') 
,(123,'M258','2015-06-03'); 

WITH cte AS (
    select *, 
    grp = row_number() over(partition by acctnbr order by effectivedate) 
    - row_number() over(partition by acctnbr, RepNbr order by effectivedate) 
    from @rep 
) 
SELECT acctnbr, RepNbr, max(effectivedate) effectivedate 
from cte 
group by acctnbr, RepNbr, grp 
order by acctnbr, max(effectivedate) desc; 
+0

eine Änderung wird in der Regel wirksam auf ein Minimum EffectiveDate nicht maximal, aber ich stimme zu, das OP macht es anders aussehen aufgrund der erwarteten Ergebnisse und Beispieldaten aus sein Auftrag. – Matt

+1

@matt, Sicher OP kann es aussortieren und wählen min/max wie benötigt. Danke für den Hinweis trotzdem. – Serg

Verwandte Themen