Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL - Kết hợp hai câu lệnh chọn thành một kết quả với LIMIT một cách hiệu quả

Bạn có thể kết hợp nhiều truy vấn với UNION , nhưng chỉ khi các truy vấn có cùng số cột. Lý tưởng nhất là các cột giống nhau, không chỉ về kiểu dữ liệu, mà còn về ý nghĩa ngữ nghĩa của chúng; tuy nhiên, MySQL không quan tâm đến ngữ nghĩa và sẽ xử lý các kiểu dữ liệu khác nhau bằng cách truyền đến một thứ gì đó chung chung hơn - vì vậy nếu cần, bạn có thể nạp chồng các cột để có các ý nghĩa khác nhau từ mỗi bảng, sau đó xác định ý nghĩa nào phù hợp trong mã cấp cao hơn của bạn (mặc dù tôi không khuyên bạn nên làm theo cách này).

Khi số lượng cột khác nhau hoặc khi bạn muốn đạt được sự liên kết dữ liệu tốt hơn / ít bị quá tải hơn từ hai truy vấn, bạn có thể chèn các cột chữ giả vào SELECT của mình các câu lệnh. Ví dụ:

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

Bạn thậm chí có thể có một số cột dành riêng cho bảng đầu tiên và những cột khác cho bảng thứ hai, chẳng hạn như chúng là NULL ở nơi khác (nhưng hãy nhớ rằng tên cột đến từ truy vấn đầu tiên, vì vậy bạn có thể muốn đảm bảo rằng tất cả chúng đều được đặt tên ở đó):

  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;

Bạn có thể thử căn chỉnh hai truy vấn của mình theo cách này, sau đó kết hợp chúng với một UNION nhà điều hành; bằng cách áp dụng LIMIT tới UNION , bạn sắp đạt được mục tiêu của mình:

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

Vấn đề duy nhất còn lại là, như đã trình bày ở trên, 10 bản ghi trở lên từ bảng đầu tiên sẽ "đẩy ra" bất kỳ bản ghi nào từ bảng thứ hai. Tuy nhiên, chúng tôi có thể sử dụng ORDER BY trong truy vấn bên ngoài để giải quyết vấn đề này.

Kết hợp tất cả lại với nhau:

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

Tất nhiên, bây giờ bạn phải xác định loại hàng bạn đang xử lý khi đọc từng bản ghi trong tập kết quả (khuyên bạn nên kiểm tra request_id và / hoặc alert_id cho NULL các giá trị; cách khác, người ta có thể thêm một cột bổ sung vào kết quả cho biết rõ ràng mỗi bản ghi bắt nguồn từ bảng nào, nhưng nó phải tương đương với điều kiện id đó các cột 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. Trong SQL / MySQL, sự khác biệt giữa ON và WHERE trong một câu lệnh nối là gì?

  2. PHP - Laravel 5 lấy dữ liệu vào bảng html từ 3 bảng cơ sở dữ liệu SQL với cột DATA làm tiêu đề

  3. Giá trị dyanmic Mysql làm bí danh

  4. Chỉ lấy tên cột như trong mảng mysql

  5. không thể tăng giới hạn tệp mở trong mariadb 10 trên centos7