sql >> Databáze >  >> RDS >> Mysql

MySQL – efektivní spojení dvou vybraných příkazů do jednoho výsledku s LIMIT

Pomocí UNION můžete kombinovat více dotazů , ale pouze v případě, že dotazy mají stejný počet sloupců. V ideálním případě jsou sloupce stejné nejen v datovém typu, ale také ve svém sémantickém významu; MySQL se však nestará o sémantiku a poradí si s různými datovými typy převedením na něco obecnějšího – takže v případě potřeby můžete přetížit sloupce, aby měly různé významy z každé tabulky, a pak určit, jaký význam je vhodný ve vašem kódu vyšší úrovně (ačkoli to nedoporučuji dělat tímto způsobem).

Když se počet sloupců liší nebo když chcete dosáhnout lepšího/méně přetíženého zarovnání dat ze dvou dotazů, můžete do SELECT vložit fiktivní doslovné sloupce prohlášení. Například:

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

Dokonce můžete mít některé sloupce vyhrazené pro první tabulku a jiné pro druhou tabulku, takže jsou NULL jinde (ale nezapomeňte, že názvy sloupců pocházejí z prvního dotazu, takže možná budete chtít zajistit, aby tam byly všechny pojmenovány):

  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;

Můžete zkusit zarovnat své dva dotazy tímto způsobem a poté je zkombinovat s UNION operátor; použitím LIMIT do UNION , jste blízko k dosažení svého cíle:

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

Jediný problém, který zůstává, je, jak je uvedeno výše, 10 nebo více záznamů z první tabulky „vytlačí“ všechny záznamy z druhé tabulky. Můžeme však použít ORDER BY ve vnějším dotazu, abyste to vyřešili.

Dát to všechno dohromady:

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

Nyní je samozřejmě na vás, abyste při čtení každého záznamu v sadě výsledků určili, s jakým typem řádku máte co do činění (doporučujeme otestovat request_id a/nebo alert_id pro NULL hodnoty; alternativně lze k výsledkům přidat další sloupec, který explicitně uvádí, ze které tabulky každý záznam pochází, ale měl by být ekvivalentní za předpokladu, že id sloupce jsou NOT NULL ).




  1. jak zobrazit celou proměnnou s mezerou v textovém poli v php

  2. Procházejte smyčkou a najděte opakovaná jména

  3. Oracle SQL návratový sloupec vypočítaný z existujících sloupců

  4. Python MySQL Connector:Nelze se připojit k serveru pomocí SSL