2017-02-15 3 views
0

Als Anfänger mit SQL, bin ich ok, einfache Aufgaben zu tun, aber ich habe gerade mit mehreren verschachtelten Abfragen kämpfen. Mein Problem ist, dass ich drei Tabellen wie folgt aus:Verschachtelte Abfragen und Join

eine Case Tabelle:

id nd date     username 
-------------------------------------------- 
1 596 2016-02-09 16:50:03 UserA 
2 967 2015-10-09 21:12:23 UserB 
3 967 2015-10-09 22:35:40 UserA 
4 967 2015-10-09 23:50:31 UserB 
5 580 2017-02-09 10:19:43 UserA 

eine Value Tabelle:

case_id labelValue_id Value   Type 
------------------------------------------------- 
1   3633    2731858342  X 
1   124    ["864","862"] X 
1   8981    -2.103   X 
1   27    443   X 
...  ...    ...   ... 
2   7890    232478   X 
2   765    0.2334   X 
...  ...    ...   ... 

und eine Label Tabelle:

id  label 
---------------------- 
3633 Value of W    
124 Value of X 
8981 Value of Y  
27  Value of Z 

Offensichtlich möchte ich diesen Tabl beitreten es. Also kann ich so etwas tun:

SELECT * 
from Case, Value, Label 
where Case.id= Value.case_id 
and Label.id = Value.labelValue_id 

aber ich bekomme so ziemlich alles, während ich genauer sein möchte.

Was ich will, ist eine Filterung auf der Case Tabelle und dann verwenden Sie die resultierenden IDs, um die beiden anderen Tabellen zu verbinden. Ich möchte:

  1. Filter der Case.nd ist so, dass, wenn es serveral Instanzen derselben nd ist, nehmen die älteste,
  2. begrenzen die Anzahl der nd die in der Abfrage. Zum Beispiel möchte ich in der Lage sein, die Tabellen für nur 2, 3, 4 usw. zu verbinden.
  3. Verwenden Sie diese Abfrage, um eine Verknüpfung in der Tabelle Value und Label zu erstellen.

Zum Beispiel kann die Ausgabe der Abfragen 1 und 2 wäre:

id nd date     username 
-------------------------------------------- 
1 596 2016-02-09 16:50:03 UserA 
2 967 2015-10-09 21:12:23 UserB 

wenn ich für 2 verschiedene nd fragen. Der nd 967 erscheint mehrmals, aber wir nehmen den ältesten.

In der Tat, ich denke, ich habe herausgefunden, wie all diese Dinge zu tun, aber ich kann/weiß nicht, wie man sie zusammenführen.

die älteste nd zu wählen, ich someting wie tun kann:

select min((date)), nd,id 
    from Case 
    group by nd 

Dann die Anzahl der nd in der Ausgabe zu begrenzen, fand ich diese (basierend auf this und that):

select *, 
@num := if(@type <> t.nd, @num + 1, 1) as row_number, 
@type := t.nd as dummy 
    from(
     select min((date)), nd,id 
     from Case 
     group by nd 
     ) as t 
     group by t.nd 
     having row_number <= 2 -- number of output 

Es funktioniert, aber ich fühle es wird langsam.

Schließlich, wenn ich versuche, einen Join mit dieser Unterabfrage und mit den zwei anderen Tabellen zu machen, läuft die Verarbeitung für immer weiter.

Während meiner Forschung konnte ich Antworten für jeden Teil des Problems finden, aber ich kann sie nicht zusammenführen. Auch für das "Zählen" -Problem, bei dem ich die Anzahl von nd begrenzen möchte, fühle ich, dass es weit hergeholt ist.

Ich weiß, das ist eine lange Frage, aber ich denke, ich vermisse etwas und ich wollte so viel Details wie möglich geben.

+0

Beginnen Sie mit jedem grundlegenden Buch oder Tutorial. Achten Sie besonders auf JOINs. – Strawberry

Antwort

0

So endlich, hier ist das, was für mich gut funktioniert:

select * 
from (
     select * 
     from Case 
     join (
      select nd as T_ND, date as T_date 
      from Case 
      where nd in (select distinct nd from Case) 
      group by T_ND Limit 5 -- <========= Limit of nd's 
     ) as t 
     on Case.nd = t.T_ND 
     where date = (select min(date) 
           from Case 
           where nd = t.T_ND) 
    ) as subquery 

    join Value 
     on Value.context_id = subquery.id 
    join Label 
     on Label.id = Value.labelValue_id 

Thank Sie @ Charlesbretana für mich auf dem richtigen Weg führen :).

0

die Falltabelle zu filtern alle, aber ältesten nds,

select * from [case] c 
where date = (Select min(date) from case 
       where nd = c.nd) 

dann nur kommen diese zu den anderen Tabellen zu beseitigen:

select * from [case] c 
    join value v on v.Case_id = c.Id 
    join label l on l.Id = v.labelValue_id 
where date = (Select min(date) from [case] 
       where nd = c.nd) 

es auf eine bestimmte Anzahl von Datensätzen zu begrenzen, gibt ein mysql spezifischer Befehl, ich denke, es Limit

select * from [case] c 
    join value v on v.Case_id = c.Id 
    join label l on l.Id = v.labelValue_id 
where date = (Select min(date) from [case] 
       where nd = c.nd) 
Limit 4 -- <=== will limit return result set to 4 rows 

genannt, wenn Sie nur wollen Reco rds für die Top-N-Werte von nd, dann geht die Grenze auf einer Unterabfrage, welche Werte von nd Einschränkung abzurufen:

select * from [case] c 
    join value v on v.Case_id = c.Id 
    join label l on l.Id = v.labelValue_id 
where date = (Select min(date) from [case] 
       where nd = c.nd) 
    and nd In (select distinct nd from [case] 
       order by nd desc Limit N) 
+0

Danke für deine Antwort, der Join-Teil hilft mir. Aber für den Grenzbereich war meiner Meinung nach nicht klar genug. Ich aktualisiere den Post und die "Value" -Tabelle. Für eine 'Case.nd', die mit der' Case.id' verknüpft ist, kann ich wie 5000 Werte in der 'Value' Tabelle erhalten. Also, mein Punkt ist nicht die Anzahl der Zeilen zu begrenzen (ein "Limit 4" erlaubt mir, die ersten 4 Werte für einen bestimmten nd zu sehen), sondern wirklich die Anzahl von nd, die verarbeitet werden. Ich hoffe es wird Sinn machen. – JoKa

+0

Ja, ich verstehe, dann brauchen Sie eine weitere Prädikat-Einschränkung für die Falltabelle .... aber Sie müssen angeben * welche * nd-Werte dann enthalten ... vorausgesetzt, Sie wollen die * höchsten * n Werte, werde ich eine andere untersuchen Lösung –

+0

Danke! Allerdings bekomme ich diesen Fehler "Fehlercode: 1235. Diese Version von MySQL unterstützt noch nicht 'LIMIT & IN/ALL/ANY/SOME Unterabfrage'. Ich bin auf SQL V5.7.17. Aber anscheinend können wir stattdessen JOIN verwenden von IN. Ich arbeite daran, ich denke, ich bin nah dran! – JoKa

Verwandte Themen