2016-08-02 5 views
0

ich in Excel 2013 arbeite und eine Verbindung zu SQL Server mit einer ODBC-VerbindungT-SQL-Wert erstmals identifizieren erscheint in Spalte

Ich habe eine Tabelle wie folgt aus:

id PhoneNumber Caller 
-------------------------------- 
1  915869850  John 
2  912586985  Mary 
3  963285874  John 
4  915869850  Richard 
5  965878965  James 
6  925869753  Richard 
8  963285874  James 

und ich muss werden fügen sie eine Spalte, die das erste Mal, wenn eine Telefonnummer identifiziert wird aufgerufen und ignoriert sie auf den nachfolgenden Zeiten ...

So:

id PhoneNumber Caller First Time 
----------------------------------------- 
1  915869850  John  1 
2  912586985  Mary  1 
3  963285874  John  1 
4  915869850  Richard 0 
5  965878965  James  1 
6  925869753  Richard 1 
8  963285874  James  0 

Ist es möglich, dies zu tun?

Können Sie mir helfen?

+0

Possible Duplikat [Get top 1 Zeile jeder Gruppe] (http://stackoverflow.com/questions/6841605/get-top-1-row-of-each-group) –

+0

@ TabAlleman ist nicht wirklich eine Duplikatsituation, weil der op nur die oberste 1 Zeile jeder Gruppe anzeigen soll, während ich in meinem Beitrag eine Spalte hinzufügen muss, um die erste Instanz der Gruppe zu identifizieren, aber trotzdem die Ganze Tabelle als normal ... – ricardomadaleno

+0

Für Stack Overflow ist es ein Duplikat, da die Technik, die zur Lösung dieses Problems verwendet wird, auch Ihr Problem löst. Das Grundproblem ist das gleiche: Wie identifiziert man die oberste 1 einer Gruppe? Ob Sie es dann verwenden, um nur die oberste 1 anzuzeigen oder eine Spalte hinzuzufügen, ist ein trivialer Unterschied. –

Antwort

0

Verwenden ROW_NUMBER() Fensterfunktion wie unten:

SELECT *, CASE WHEN (ROW_NUMBER() OVER 
    (PARTITION BY PhoneNumber ORDER BY id))=1 THEN 1 ELSE 0 END FirstTime 
FROM Src 
ORDER BY id 
+0

Das funktioniert super !! Wäre es möglich, eine Bedingung hinzuzufügen, so dass sie das erste Mal an einem Wochentag identifizieren würde? – ricardomadaleno

2

Unter der Annahme, SQL Server 2005+ Sie ROW_NUMBER und dann einen CASE Ausdruck verwenden:

WITH CTE AS 
(
    SELECT *, 
      RN = ROW_NUMBER() OVER(PARTITION BY PhoneNumber ORDER BY id) 
    FROM dbo.Phones 
) 
SELECT id, 
     PhoneNumber, 
     [Caller], 
     CASE WHEN RN = 1 THEN 1 ELSE 0 END [First Time] 
FROM CTE; 
+0

Sie könnten RN auch in ein Bit konvertieren, anstatt einen Case-Ausdruck zu verwenden. Konvertiere (Bit, RN) als FirstTime. –

+0

@SeanLange Würde das nicht für jeden Wert "1" zurückgeben? – Lamak

+0

LOL ja, ich nehme an, es wäre, wenn Sie nicht ein wenig Mathematik RN-1 (was natürlich völlig sinnlos und albern wäre). –

0

Der klassische Ansatz dazu war ein Self-Join oder eine skalare Unterabfrage wie folgt aus:

select id, PhoneNumber, 
    case 
     when id = (
      select min(p2.id) from <Phones> p2 
      where p2.PhoneNumber = p.PhoneNumber 
     ) then 1 else 0 
    end as [First Time] 
from <Phones> p 
1

Anothe r Lösung:

WITH FirstCallList AS 
(
SELECT 
    MIN([id]) AS FirstIdForNumber 
FROM 
    Calls 
GROUP BY 
    PhoneNumber 
) 
SELECT 
    Calls.id 
    ,Calls.PhoneNumber 
    ,Calls.Caller 
    ,CASE WHEN FirstCallList.FirstIdForNumber IS NULL THEN 0 ELSE 1 END AS FirstTime 
FROM 
    Calls 
    LEFT OUTER JOIN FirstCallList ON Calls.id = FirstCallList.FirstIdForNumber 
ORDER BY 
    Calls.id 
; 
+0

Keine Notwendigkeit für eine äußere Verbindung hier. – shawnt00

+0

Nicht folgen. Die Anforderungen von OP bestehen darin, Zeilen für Aufrufe zu sehen, die NICHT an erster Stelle stehen, sowie solche, die es waren. Post-Beispiel, wie Sie Join ändern und immer noch das gleiche Ergebnis erhalten würden? –

+0

Ich falsch gelesen und Ihnen ist richtig. Meine Entschuldigung wird sein, dass das Anzeigen von Code auf dem Bildschirm meines Telefons ein kleiner Streit ist, und ich muss verpasst haben, dass Sie oh-Telefonnummer nicht beitraten. Hier ist, was ich abgebildet habe: http://rextester.com/LKDV75532 – shawnt00

Verwandte Themen