sql >> Databasteknik >  >> RDS >> Mysql

MySQL - Kombinera två utvalda uttalanden till ett resultat med LIMIT effektivt

Du kan kombinera flera frågor med UNION , men bara om frågorna har samma antal kolumner. Helst är kolumnerna desamma, inte bara i datatyp, utan också i sin semantiska betydelse; MySQL bryr sig dock inte om semantiken och kommer att hantera olika datatyper genom att övergå till något mer generiskt - så vid behov kan överbelasta kolumnerna så att de har olika betydelser från varje tabell och bestäm sedan vilken betydelse som är lämplig i din kod på högre nivå (även om jag inte rekommenderar att du gör det på det här sättet).

När antalet kolumner skiljer sig, eller när du vill uppnå en bättre/mindre överbelastad justering av data från två frågor, kan du infoga dummy literal-kolumner i din SELECT uttalanden. Till exempel:

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

Du kan till och med ha vissa kolumner reserverade för den första tabellen och andra för den andra tabellen, så att de är NULL någon annanstans (men kom ihåg att kolumnnamnen kommer från den första frågan, så du kanske vill försäkra dig om att de alla är namngivna där):

  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 prova att anpassa dina två frågor på det här sättet och sedan kombinera dem med en UNION operatör; genom att använda LIMIT till UNION , du är nära att nå ditt mål:

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

Det enda problemet som återstår är att, som presenterats ovan, 10 eller fler poster från den första tabellen kommer att "skjuta ut" alla poster från den andra. Däremot kan vi använda en ORDER BY i den yttre frågan för att lösa detta.

Att sätta ihop allt:

(
  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;

Naturligtvis är det nu upp till dig att avgöra vilken typ av rad du har att göra med när du läser varje post i resultatuppsättningen (föreslå att du testar request_id och/eller alert_id för NULL värden; alternativt kan man lägga till ytterligare en kolumn till resultaten som uttryckligen anger vilken tabell varje post kommer från, men den bör vara likvärdig förutsatt att dessa id kolumner är NOT NULL ).




  1. VÄLJ DISTINKT endast de fyra första siffrorna

  2. oracle + java-kodningsproblem vid infogning

  3. iOS Lägga upp bilder och data till PHP mySQL Database

  4. Prioritera en kolumn framför en annan