Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL - Efektywne łączenie dwóch instrukcji select w jeden wynik za pomocą LIMIT

Możesz łączyć wiele zapytań za pomocą UNION , ale tylko wtedy, gdy zapytania mają taką samą liczbę kolumn. Najlepiej byłoby, gdyby kolumny były takie same, nie tylko pod względem typu danych, ale także ich znaczenia semantycznego; jednak MySQL nie dba o semantykę i będzie obsługiwał różne typy danych, rzutując na coś bardziej ogólnego - więc w razie potrzeby możesz przeciąż kolumny, aby miały różne znaczenia z każdej tabeli, a następnie określ, jakie znaczenie jest odpowiednie w kodzie wyższego poziomu (chociaż nie polecam robienia tego w ten sposób).

Gdy liczba kolumn jest różna lub gdy chcesz uzyskać lepsze/mniej przeciążone wyrównanie danych z dwóch zapytań, możesz wstawić kolumny fikcyjne literału do SELECT sprawozdania. Na przykład:

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

Możesz nawet mieć niektóre kolumny zarezerwowane dla pierwszej tabeli, a inne dla drugiej tabeli, tak aby były NULL gdzie indziej (ale pamiętaj, że nazwy kolumn pochodzą z pierwszego zapytania, więc możesz chcieć się upewnić, że wszystkie są tam wymienione):

  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;

Możesz spróbować wyrównać swoje dwa zapytania w ten sposób, a następnie połączyć je z UNION operator; przez zastosowanie LIMIT do UNION , jesteś blisko osiągnięcia celu:

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

Jedyną kwestią, która pozostaje, jest to, że, jak przedstawiono powyżej, 10 lub więcej rekordów z pierwszej tabeli „wypchnie” wszystkie rekordy z drugiej. Możemy jednak użyć ORDER BY w zewnętrznym zapytaniu, aby rozwiązać ten problem.

Wszystko razem:

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

Oczywiście teraz od Ciebie zależy określenie, z jakim typem wiersza masz do czynienia, czytając każdy rekord w zestawie wyników (sugeruj przetestowanie request_id i/lub alert_id dla NULL wartości; alternatywnie można dodać do wyników dodatkową kolumnę, która wyraźnie określa, z której tabeli pochodzi każdy rekord, ale powinna być równoważna pod warunkiem, że te id kolumny są 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. odpowiedź danych ajax zawsze 0 w php mysql

  2. Jak transponować wiersze MySQL i powtarzać nagłówki kolumn?

  3. Jak edytować dane w mysql za pomocą modalnego

  4. Jak zarejestrować formularz użytkownika ze wszystkimi nazwami pól dynamicznych w php

  5. MYSQL - WYBIERZ IP v4/v6, inet_pton i bin2hex