none
T-SQL Bitte um Hilfe bei einer Abfrage RRS feed

  • Frage

  • Hallo, ich habe eine Tabelle wie die folgende

    peron_id      item1        item2      item3      item4

    120              good         bad          yes           no
    120           average    average       no           yes
    120              bad          bad           no            no
    120             good        good          yes          yes


    Ich möchte den prozentuellen Anteil von goods-averages-bads bzw. yes-nos für jede Spalte, bezogen auf eine person_id.
    Muss ich mehrere seperate Queries wie diesen machen:
    SET @anzahl_item1 = SELECT COUNT(item1) FROM table_name WHERE item1 = 'good' AND person_id = 120 GROUP BY person_id;
    SET @anzahl_gesamt = SELECT COUNT(person_id) FROM table_name WHERE person_id = @id;
    SET @prozent_item1 = (@anzahl_item1 * 100)/@anzahl_gesamt;
    Und das für jeden möglichen Wert und dann noch für jede Spalte ? Ich denke, T_SQL bietet hierfür sicher etwas komfortableres an.
    Bitte helft mir. Danke
    Donnerstag, 18. Februar 2010 09:57

Antworten

  • Hallo!
    Es wäre etwas einfacher, wenn Du ein Result-Set angegeben hättest, an dem man sich orientieren kann.
    Für Item1 müßte das wohl jetzt so aussehen:

    with cte as
    (
    SELECT person_id, COUNT(*) as Anzahl_gesamt
    FROM @tab 
    GROUP BY person_id
    )
    select t.person_id, t.item1, COUNT(*) as Anz_Item1, min(cte.Anzahl_gesamt) as Gesamt, COUNT(*)  * 100 / min(cte.Anzahl_gesamt) as Anteil_Item1
    from @tab t
    inner join cte on t.person_id = cte.person_id
    group by t.person_id, t.item1;
    Einen Join über die verschiedenen Auswertungen wirst Du wohl nicht hinbekommen, da jedes Item unterschiedliche Anzahl von Zeilen generiert.
    Einen schönen Tag noch, Christoph Muthmann Microsoft SQL Server MVP, http://www.insidesql.org
    Freitag, 19. Februar 2010 14:19

Alle Antworten

  • Hallo!
    Lass doch einfach die Where-Bedingung weg und zähle die DISTINCT Items.

    Declare @Tab as Table(person_id  int, item1 varchar(10),  item2 varchar(10), item3 varchar(10), item4 varchar(10))
    
    insert into @Tab(person_id,  item1, item2, item3, item4) values(120, 'good',   'bad',     'yes', 'no');
    insert into @Tab(person_id,  item1, item2, item3, item4) values(120, 'average','average', 'no',  'yes');
    insert into @Tab(person_id,  item1, item2, item3, item4) values(120, 'bad',    'bad',     'no',  'no');
    insert into @Tab(person_id,  item1, item2, item3, item4) values(120, 'good',   'good',    'yes', 'yes');
    
    
    
    SELECT person_id, COUNT(distinct item1) as Anzahl_item1, COUNT(distinct item2) as Anzahl_item2, 
    COUNT(distinct item3) as Anzahl_item3, COUNT(distinct item4) as Anzahl_item4, COUNT(*) as Anzahl_gesamt,
    COUNT(distinct item1) * 100 /  COUNT(*) as Prozent_item1,
    COUNT(distinct item2) * 100 /  COUNT(*) as Prozent_item2,
    COUNT(distinct item3) * 100 /  COUNT(*) as Prozent_item3,
    COUNT(distinct item4) * 100 /  COUNT(*) as Prozent_item4
    FROM @tab 
    GROUP BY person_id;
    
    
    
    
    

    Einen schönen Tag noch, Christoph Muthmann Microsoft SQL Server MVP, http://www.insidesql.org
    Freitag, 19. Februar 2010 07:44
  • Hallo Christoph, danke für deine Antwort.
    Deine Lösung ermittelt den Prozentsatz der Werte, die unterschiedlich sind. Ich bräuchte aber die Prozentsätze aller abgegebenen Wertungen pro Spalte für die jeweilige person_id. Also, für Person1 wurde bei item1 3 mal 'good'  und 5 mal 'average' gewählt und das ganze in Prozent
    (anzahl item1 * 100 / anzahl gesamt).
    Freitag, 19. Februar 2010 11:23
  • Hallo!
    Es wäre etwas einfacher, wenn Du ein Result-Set angegeben hättest, an dem man sich orientieren kann.
    Für Item1 müßte das wohl jetzt so aussehen:

    with cte as
    (
    SELECT person_id, COUNT(*) as Anzahl_gesamt
    FROM @tab 
    GROUP BY person_id
    )
    select t.person_id, t.item1, COUNT(*) as Anz_Item1, min(cte.Anzahl_gesamt) as Gesamt, COUNT(*)  * 100 / min(cte.Anzahl_gesamt) as Anteil_Item1
    from @tab t
    inner join cte on t.person_id = cte.person_id
    group by t.person_id, t.item1;
    Einen Join über die verschiedenen Auswertungen wirst Du wohl nicht hinbekommen, da jedes Item unterschiedliche Anzahl von Zeilen generiert.
    Einen schönen Tag noch, Christoph Muthmann Microsoft SQL Server MVP, http://www.insidesql.org
    Freitag, 19. Februar 2010 14:19
  • @Christoph, vielen Dank. Man lernt nie aus. Eines ist mir noch nicht klar: warum verwendest du min() bei cte.Anzahl_gesamt ?
    Danke
    Samstag, 20. Februar 2010 12:11
  • Da ich eine Gruppierung über Person und item1 bilden muss, sind nur Aggregatsfunktionen zugelassen. Ob Du hier Min(), Max() oder Avg() verwendest, dürfte am Ergebnis nichts ändern. Min() finde ich noch am naheliegendsten. ;-)
    Einen schönen Tag noch, Christoph Muthmann Microsoft SQL Server MVP, http://www.insidesql.org
    Montag, 22. Februar 2010 08:00
  • OK, alles klar.
    Danke
    Montag, 22. Februar 2010 16:00