Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL - Ефективно комбиниране на два оператора за избор в един резултат с LIMIT

Можете да комбинирате множество заявки с UNION , но само ако заявките имат еднакъв брой колони. В идеалния случай колоните са еднакви не само като тип данни, но и като семантично значение; обаче, MySQL не се интересува от семантиката и ще се справи с различни типове данни чрез преобразуване до нещо по-общо - така че ако е необходимо, вие можете претоварете колоните, за да имат различни значения от всяка таблица, след което определете какво значение е подходящо във вашия код от по-високо ниво (въпреки че не препоръчвам да го правите по този начин).

Когато броят на колоните се различава или когато искате да постигнете по-добро/по-малко претоварено подравняване на данни от две заявки, можете да вмъкнете фиктивни литерални колони във вашия SELECT изявления. Например:

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

Можете дори да имате някои колони, запазени за първата таблица и други за втората таблица, така че да са NULL другаде (но не забравяйте, че имената на колоните идват от първата заявка, така че можете да се уверите, че всички те са именувани там):

  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;

Можете да опитате да подравните двете си заявки по този начин, след което да ги комбинирате с UNION оператор; чрез прилагане на LIMIT към UNION , вие сте близо до постигането на целта си:

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

Единственият проблем, който остава, е, че както е представено по-горе, 10 или повече записа от първата таблица ще „изтласкат“ всички записи от втората. Можем обаче да използваме ORDER BY във външната заявка за решаване на това.

Събирайки всичко заедно:

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

Разбира се, сега зависи от вас да определите с какъв тип ред си имате работа, докато четете всеки запис в набора с резултати (предлагаме ви да тествате request_id и/или alert_id за NULL стойности; алтернативно може да се добави допълнителна колона към резултатите, която изрично посочва от коя таблица произхожда всеки запис, но тя трябва да е еквивалентна, при условие че тези id колоните са NOT NULL ).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql:отказан достъп до information_schema

  2. MySQL MIN() и MAX() с LIMIT

  3. Извличане на редове, групирани по час с MySQL

  4. SQL - Намерете пълна дума в текста

  5. Трябва да изтегля данни въз основа на точната им последователност в масив