2011-06-18 35 views
5

Tôi đang cố gắng UNION hai truy vấn có chứa cả ORDER BY. Như tôi đã phát hiện, bạn không thể đặt hàng bằng các truy vấn là một phần của UNION. Tôi chỉ không biết cách khác để thực hiện truy vấn này sau đó. Hãy để tôi giải thích những gì tôi đang cố gắng làm.MySQL UNION 2 truy vấn chứa ORDER BYs

  1. Tôi cố gắng để chọn 40 hồ sơ mới nhất và từ danh sách đó chọn một tập hợp ngẫu nhiên của 20. sau đó tôi muốn đoàn rằng với:
  2. Chọn 40 hồ sơ ngẫu nhiên mà hồ sơ không rơi vào 40 hồ sơ gần đây nhất được truy vấn trong tập đầu tiên
  3. Sắp xếp ngẫu nhiên toàn bộ 60 bản ghi đó.

Tôi nhận thức được hậu quả hiệu quả của việc sử dụng) chức năng (Rand

SELECT profileId 
    FROM (SELECT profileId 
      FROM profile profile2 
     WHERE profile2.profilePublishDate <= Now() 
     ORDER BY profile2.profilePublishDate DESC 
     LIMIT 0,40) AS profile1 
ORDER BY RAND() 
    LIMIT 0,20 
UNION (SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (SELECT profileId 
            FROM profile profile4 
           WHERE profile4.profilePublishDate <= Now() 
           ORDER BY profile4.profilePublishDate DESC 
           LIMIT 0,40)  
    ORDER BY RAND()  
     LIMIT 0,40) as profile3 
ORDER BY RAND() 

UPDATE: Đây là giải pháp dựa vào sự giúp đỡ Abhay của dưới đây (nhờ Abhay):

SELECT * 
FROM 
(
    (
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    ) 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT * FROM 
      (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) AS temp2 
     ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

Trả lời

5

Đây là giải pháp của bạn:

SELECT * 
FROM 
(
    **(** 
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    **)** 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

Những thay đổi mà tôi đã thực hiện là:

  1. mỗi truy vấn của bạn là một phần của UNION nên được bọc trong dấu ngoặc (được in đậm cho truy vấn đầu tiên; số thứ hai đã được bọc)
  2. xóa bí danh profile3 cho truy vấn thứ 2 của bạn
  3. cho số ORDER BY RAND() cuối cùng, bạn phải tạo thứ e Kết quả UNION đến một bảng có nguồn gốc; Tôi đã cấp cho nó TEMP làm bí danh

Tôi chưa thử nghiệm truy vấn trên nhưng tôi hy vọng nó sẽ hoạt động. Hãy cho tôi biết những phát hiện của bạn.

+1

Cảm ơn - Giải pháp của bạn đã giải quyết được vấn đề của tôi, tuy nhiên một lỗi mới phát sinh (Phiên bản MySQL này chưa hỗ trợ 'LIMIT & IN/ALL/ANY/MỘT SỐ truy vấn phụ ') mà tôi cũng đã giải quyết với một lựa chọn khác và đăng truy vấn đầy đủ ở trên trong bài đăng gốc của tôi. Cảm ơn sự giúp đỡ của bạn trong việc giải quyết vấn đề này. – Cheeky

+0

@Cheeky: Có, đây là cách để giải quyết nó, với những hạn chế mà MySQL đặt ra :) –

1

Bạn có thể bao gồm toàn bộ truy vấn trong một lựa chọn khác (để thực hiện là chọn lựa) và ORDER BY RAND() trên tập hợp kết quả đó. Tuy nhiên, điều này khá phức tạp (nhiều câu hỏi ngẫu nhiên là ORDER BY khi bạn chỉ yêu cầu một), vì vậy có thể sẽ tốn ít bộ xử lý hơn để thu thập tập dữ liệu được sắp xếp (tức là chỉ UNION của profile1profile3) thành một mảng bằng ngôn ngữ bạn chọn và ngẫu nhiên thứ tự của mảng đó.

+0

Anh ấy cần bên trong 'ORDER BY RAND()' –

+0

@ypercube tại sao bên trong 'ORDER BY' được yêu cầu khi toàn bộ kết quả được đặt lại? – Andy

+0

vì nó được sử dụng kết hợp với 'LIMIT 40' để chọn 40 hàng ngẫu nhiên từ một phần của bảng và 20 hàng ngẫu nhiên từ một hàng khác (với' LIMIT 20'). –