sql >> Database teknologi >  >> RDS >> Mysql

MySQL - Kombinerer to udvalgte udsagn til ét resultat med LIMIT effektivt

Du kan kombinere flere forespørgsler med UNION , men kun hvis forespørgslerne har det samme antal kolonner. Ideelt set er kolonnerne de samme, ikke kun i datatype, men også i deres semantiske betydning; MySQL er dog ligeglad med semantikken og vil håndtere forskellige datatyper ved at lægge op til noget mere generisk - så om nødvendigt kan overbelast kolonnerne til at have forskellige betydninger fra hver tabel, og afgør derefter, hvilken betydning der er passende i din kode på højere niveau (selvom jeg ikke anbefaler at gøre det på denne måde).

Når antallet af kolonner er forskelligt, eller når du ønsker at opnå en bedre/mindre overbelastet justering af data fra to forespørgsler, kan du indsætte dummy literal-kolonner i din SELECT udsagn. For eksempel:

SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
 

Du kan endda have nogle kolonner reserveret til den første tabel og andre til den anden tabel, sådan at de er NULL andre steder (men husk, at kolonnenavnene kommer fra den første forespørgsel, så du ønsker måske at sikre, at de alle er navngivet der):

SELECT a, b, c, d, NULL AS e, NULL AS f, NULL AS g FROM t1 UNION ALL -- specify ALL because default is DISTINCT, which is wasted here SELECT NULL, NULL, NULL, NULL, a, b, c FROM t2;

Du kan prøve at justere dine to forespørgsler på denne måde og derefter kombinere dem med en UNION operatør; ved at anvende LIMIT til UNION , du er tæt på at nå dit mål:

  (SELECT ...)
UNION
  (SELECT ...)
LIMIT 10;
 

Det eneste problem, der er tilbage, er, at, som præsenteret ovenfor, 10 eller flere poster fra den første tabel vil "skubbe" alle poster ud fra den anden. Vi kan dog bruge en ORDER BY i den ydre forespørgsel for at løse dette.

At sætte det hele sammen:

( SELECT dr.request_time AS event_time, m.member_name, -- shared columns dr.request_id, dr.member1, dr.member2, -- request-only columns NULL AS alert_id, NULL AS alerter_id, -- alert-only columns NULL AS alertee_id, NULL AS type FROM dating_requests dr JOIN members m ON dr.member1=m.member_id WHERE dr.member2=:loggedin_id ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION ) UNION ALL ( SELECT da.alert_time AS event_time, m.member_name, -- shared columns NULL, NULL, NULL, -- request-only columns da.alert_id, da.alerter_id, da.alertee_id, da.type -- alert-only columns FROM dating_alerts da JOIN dating_alerts_status das USING (alert_id, alertee_id) JOIN members m ON da.alerter_id=m.member_id WHERE da.alertee_id=:loggedin_id AND da.type='platonic' AND das.viewed='0' AND das.viewed_time<da.alert_time ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION ) ORDER BY event_time LIMIT 10;

Nu er det selvfølgelig op til dig at bestemme, hvilken type række du har at gøre med, når du læser hver post i resultatsættet (foreslå, at du tester request_id og/eller alert_id for NULL værdier; alternativt kan man tilføje en ekstra kolonne til resultaterne, der udtrykkeligt angiver, fra hvilken tabel hver post stammer fra, men den bør være ækvivalent forudsat disse id kolonner er NOT NULL ).




  1. (Én tabel) indsæt rækker

  2. Find de seneste objektændringer i SQL Server-databasen

  3. Hurtigste måde at få XAMPP eller WAMP op på Win7 64-bit?

  4. Brug where-forespørgsler i JSONB-datatype i Rails Postgres