2016-05-06 8 views
1

Ich habe mehrere Antworten auf verwandte Fragen gelesen, aber keiner von ihnen kann auf diesen Fall angewendet werden.SQL-Get höchsten Datensatz aus der Gruppe an einer anderen Tabelle

Ich habe eine Tabelle TableA wo mehrere Gruppen aufgeführt sind, mit ihrer Punktzahl:

GROUP|SCORE 

Blue | 0  
Green| 0  
Red | 0  
Orange| 0 

Auf einem anderen Tisch TableB habe ich die Teile jeder Gruppe und ihre individuellen Score (Status), die drei haben verschiedene Werte:

- G (Good) 
- A (Average) 
- B (Bad) 

So tableB ist:

GROUP|PART|STATUS 

Blue | 3H2| A 
Blue | 4NQ| G 
Blue | W9X| A 
Green| 65D| G 
Red | 73F| B 
Red | 91G| A 

Ich brauche die Partitur auf TableA auf folgende Weise zu aktualisieren:

  • Wenn der beste Status zwischen den Teilen der Gruppe G, Gruppe-Score ist 3
  • Wenn der beste Status zwischen den Teilen der Gruppe ist A, Gruppenbewertung 2
  • Wenn der beste Status zwischen den Teilen der Gruppe B ist, Gruppen Score ist 1

ich ein paar Tage gewesen geht um thi s und ich kann keine Lösung finden. Danke Jungs. Btw, verwende ich Zugang 2013

+0

Zu allererst Sie eine Tabelle für den Status haben sollten den Rang enthält, So müssen Abfragen nicht selbst wissen, ob Status 'A' höher als 'G' usw. ist. Dann sollten Sie den Score in Tabelle A überhaupt nicht speichern, weil das überflüssig wäre. Wie Sie selbst sagen: Der Status einer Gruppe kann aus Tabelle B ermittelt werden. –

+0

@ThorstenKettner um zu wissen, welcher Rang höher ist, könnte er 'CASE Ausdruck' verwenden. –

+1

@Stanislovas Kalašnikovas: Ja, in jeder Frage. Und mach niemals Tippfehler. Und wenn Sie den Status "H" für schrecklich einführen möchten, müssen alle Abfragen geändert werden. Sie könnten genauso gut Buchstaben für die Gruppen verwenden. G wäre "Grün" und "R" wäre "Rot" und wieder könnten Sie einen CASE-Ausdruck verwenden. Verstehst du, was ich meine? :-) –

Antwort

0

In SQL-Server Sie in folgenden tun könnte:

QUERY

update a 
set a.SCORE = MaxSTATUS 
from #a a 
join (select GROUP_, MAX(case when b.STATUS_ = 'G' then 3 
           when b.STATUS_ = 'A' then 2 
           when b.STATUS_ = 'B' then 1 
          end) MaxSTATUS 
     from #b b 
     group by GROUP_ 

) b ON a.GROUP_ = b.GROUP_ 

select * from #a 

SAMPLE DATA

CREATE TABLE #a 
(
GROUP_ NVARCHAR(60), 
SCORE INT 
) 
INSERT INTO #a VALUES 
    ('Blue',0) 
,('Green',0) 
,('Red',0) 
,('Orange',0) 

CREATE TABLE #b 
(
GROUP_ NVARCHAR(60), 
PART NVARCHAR(60), 
STATUS_ NVARCHAR(60), 
) 
INSERT INTO #b VALUES 
    ('Blue','3H2','A') 
,('Blue','4NQ','G') 
,('Blue','W9X','A') 
,('Green','65D','G') 
,('Red','73F','B') 
,('Red','91G','A') 

OUPUT

GROUP_ SCORE 
Blue 3 
Green 3 
Red  2 
Orange 0 
+0

Ich habe versucht, Ihre Antwort auf Zugang zu adaptieren, aber ich kann es nicht funktionieren: ‚UPDATE (A INNER JOIN (SELECT B.GROUP, MAX ( SWITCH ( B.STATUS = "G", "3", B.STATUS = "A", "2", B.STATUS = "B", "1")), wie MaxSTATUS FROM A, B ON A.GROUP = B.GROUP Gruppe nach GROUP) als c SET A.SCORE = c.MaxSTATUS ' Könnten Sie eine zugriffsfreundliche Lösung geben? Ich mag Ihren Ansatz – GDMM1414

+0

Sorry für schlechte Formatierung in den Kommentar, es ist mein erstes Mal hier schreiben – GDMM1414

2

Wie ich bereits in den Kommentaren erwähnt habe: Speichern Sie den Score nicht redundant; es ist implizit in TabelleB enthalten. Und um Ihre Datenbank gerade eine Statustabelle vorstellen:

 
STATUS DESCRIPTION SCORE 
G  Good   3 
A  Avarage  2 
B  Bad   1 

Wenn Sie die Punktzahl für jede Farbgruppe verwenden diese Abfrage zum Beispiel auswählen möchten:

select b.colorgroup, max(s.score) as maxscore 
from tableb as b 
join status as s on s.status = b.status 
group by b.colorgroup; 

zwei alternative Möglichkeiten, um die gleiche Abfrage schreiben :

select 
    colorgroup, 
    (
    select max(score) 
    from status as s 
    where s.status = b.status 
) as maxscore 
from tableb as b; 

und

select b.colorgroup, s.maxscore 
from tableb as b 
join 
(
    select status, max(score) as maxscore 
    from status 
    group by status 
) as s on s.status = b.status; 

(Übrigens: Ich rief Ihre Gruppe colorgroup, weil GROUP ist ein reservierter Name in SQL.)


UPDATE Sie sagen, Sie nicht eine Tabelle in der Datenbank hinzufügen. Sie müssen also leider die Punktzahl in der Abfrage selbst auswerten. In Standard-SQL würden Sie CASE WHEN verwenden, die MS Access nicht bietet. MS Access bietet IIF statt:

select 
    colorgroup, 
    max(iif(status = 'G', 3, iif(status = 'A', 2, 1))) as maxscore 
from tableb 
group by colorgroup; 

Wenn Sie auch die Spalte in tableA verwenden müssen, und speichern redundant, zu verwenden:

update tablea as a 
set score = 
(
    select 
    max(iif(status = 'G', 3, iif(status = 'A', 2, 1))) as maxscore 
    from tableb as b 
    where b.colorgroup = a.colorgroup 
); 
+0

Ich stimme zu, das wäre die einfachste und beste Möglichkeit, es zu tun, aber aus unerfindlichen Gründen muss ich es machen, ohne die Tabellen zu ändern oder neue schaffen. Irgendeine Idee, wie es geht? Danke – GDMM1414

+0

Okay. Die Abfrage ist einfach genug, um zu schreiben, aber es ist schade, dass Sie die schlampige Datenbank nicht korrigieren können. In meinem Update erfahren Sie, wie bedingte Ausdrücke in MS Access aggregiert werden. –

+0

Danke. Bei Verwendung der letzten Abfrage erhalte ich jedoch einen Fehler: "Der Benutzer muss eine aktualisierbare Abfrage verwenden". Warum? Der Fehler ist ziemlich überraschend, da die Abfrage nicht kompliziert aussieht. – GDMM1414