none
gruppierter select mit Bedingung RRS feed

  • Frage

  • Hallo,

    ich habe folgendes Problem:

    In einer Zuordnungstabelle werden jedem Kunden (z.b. einer Firma) ein bis mehrere Accounts (z.b. für jeden Mitarbeiter der Firma) zugeordnet. Jeder dieser Accounts gehört einer Gruppe an.

     Ich habe also die 'kundenid', den 'account'  und die 'gruppenid'.

    Nun möchte ich alle Kunden herausfiltern, die erstens mehrere accounts besitzen und zweitens deren accounts verschiedenen Gruppen angehören.

    Im Moment bin ich so weit, dass ich schonmal alle Kunden selektiere, die mehr als einen Account besitzen und die Anzahl dieser zähle:

    SELECT kundenid, count(gruppenid) Anzahl FROM kunden

    GROUP BY kundenid HAVING count(gruppenid) > 1

    Aus dieser Liste möchte ich nun noch jene Kunden selektieren, deren Accounts verschiedenen Gruppen zugehörig sind.

    Das Ergebnis konnte ich mühsam mit Hilfe mehrerer temporärer Tabellen erlangen. Nun würde ich gern wissen, ob es nicht eine elegantere Lösung gibt?


    Freitag, 7. Dezember 2012 14:26

Antworten

  • Hallo Alexander,

    das kann man sehr schön mit CTE lösen. Hier mal ein "Schuss aus der Hüfte"

    DECLARE	@k TABLE
    (
    	Id				int			NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
    	CustomerName	varchar(40)	NOT NULL
    );
    
    DECLARE @a TABLE
    (
    	EmployeeId		int			NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
    	CustomerId		int			NOT NULL,
    	Employee		varchar(40)	NOT NULL,
    	GroupId			int			NOT NULL	DEFAULT (0)
    );
    
    
    -- Ein paar Companies
    INSERT INTO @k
    VALUES
    ('Company1'),
    ('Company2'),
    ('Company3')
    
    -- Ein paar Mitarbeiter
    INSERT INTO @a
    VALUES
    (1, 'Uwe Ricken', 1),
    (1, 'Uwe Ricken', 2),
    (1, 'Uwe Ricken', 3),
    (2, 'Beate Meyer', 1),
    (2, 'Beat Müller', 1),
    (2, 'Klaus Meier', 2),
    (3, 'Michael Müller', 1),
    (3, 'Donald Duck', 3)
    
    
    ;WITH cte
    AS
    (
    	SELECT	ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY GroupId)	AS	RowNo,
    			a.CustomerId
    	FROM	@a a
    )
    SELECT	--DISTINCT
    		k.*
    FROM	@k k INNER JOIN cte c
    		ON	(k.Id = c.CustomerId)
    WHERE	c.RowNo > 2

    Mehr Informationen zu CTE und ROW_NUMBER findest Du hier:

    CTE: http://msdn.microsoft.com/de-de/library/ms190766(v=sql.105).as

    RowNumber:http://msdn.microsoft.com/de-de/library/ms186734.aspx


    Uwe Ricken

    MCITP Database Administrator 2005
    MCITP Database Administrator 2008
    MCITP Microsoft SQL Server 2008, Database Development

    db Berater GmbH
    http://www-db-berater.de
    SQL Server Blog (german only)

    Freitag, 7. Dezember 2012 15:10