2009-10-05 22 views
6

Tôi bằng cách nào đó cần tính năng này, nhưng MySQL không hỗ trợ tính năng này vào lúc này.Làm thế nào để hack MySQL GROUP_CONCAT để tìm nạp một số hàng hạn chế?

Tôi đang sử dụng GROUP_CONCAT(CONCAT(...)) để tạo nội dung giống như xml.

Nhưng khi kích thước vượt quá giới hạn, xml chỉ bị hỏng!

Vì vậy, tôi phải bằng cách nào đó làm cho nó chỉ lấy 5 hàng!

+0

tăng group_concat_max_len giá trị trong my.cnf – Omesh

+1

có thể bạn có thể nhận được câu trả lời của bạn ở đây http://stackoverflow.com/questions/3378324/limit-ignored-in-query-with-group-concat http://stackoverflow.com/questions/23608464/group-concat-with-limit –

Trả lời

2

Sử dụng bảng tạm thời/truy vấn phụ để giới hạn kết quả? Nếu không nhìn thấy truy vấn của bạn, thật khó để đưa ra lời khuyên chắc chắn cho tuyến đường đó.

Tuy nhiên, bạn có thể thấy cài đặt group_concat_max_len hữu ích hơn. Nó kiểm soát độ dài tối đa của một hoạt động GROUP_CONCAT, với độ dài chuỗi. Hãy nâng nó lên để tránh bị vỡ GROUP_CONCAT s, khi bạn không thể đủ khả năng giới hạn kết quả.

2

Không thực sự là một câu trả lời cho câu hỏi của bạn, nhưng một ref cho những người khác, những người cũng muốn sử dụng một điều khoản LIMIT trong GROUP_CONCAT():

Một feature-request đã được nộp từ lâu các nhà phát triển MySql. Chưa thực hiện :-(

4

Một ví dụ cho Charles câu trả lời:

cơ bản:

SELECT GROUP_CONCAT(field) FROM (SELECT field FROM table LIMIT 200) 

mở rộng:

CAST có thể hữu ích nếu kết quả được cắt ngắn bởi đệm:

SELECT CAST(GROUP_CONCAT(field) AS CHAR(2048)) FROM (SELECT field FROM table LIMIT 200) 
+0

Có, nó sẽ hoạt động. Nhưng nó sẽ cần một kết cấu phức tạp hơn cho một truy vấn với 'GROUP BY'. –

+0

Tôi gặp lỗi "Mỗi bảng có nguồn gốc phải có bí danh riêng" khi sử dụng truy vấn đầu tiên. Để khắc phục điều đó, tôi đã thay đổi nó thành "SELECT GROUP_CONCAT (trường) TỪ (SELECT trường FROM bảng LIMIT 200) AS bí danh" Cảm ơn bạn đã trả lời. – Henry

15

Tôi đã làm việc xung quanh việc này bằng cách sử dụng SUBSTRING_INDEX.

Ví dụ:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(Field1 SEPARATOR ','), ',', [# of elements to return]) 
FROM Table1; 
+0

Nó trả về blob, nhưng cái này hoạt động. –

0

Đối với những trường hợp bạn không thể sử dụng một bảng temp, Cách tốt nhất mà tôi biết là để chọn một tách che khuất và sau đó cắt ngắn bắt đầu từ trường hợp đầu tiên của nhân vật nói. Ví dụ này sử dụng ký tự NUL.

select substring_index(group_concat(field separator '\0'), '\0', 5) from table;

đâu field là tên của lĩnh vực này, 5 là số lượng kết quả.

Hạn chế là nếu hàng đầu tiên của bạn chứa ký tự đó, nó sẽ là một phần kết quả.

Giải pháp thay thế sẽ là thay thế '\0' bằng chuỗi ngẫu nhiên dài hơn.

Thật hữu ích khi biết rằng field có thể được thay thế để bao gồm thêm thông tin bằng cách sử dụng concat.

Hãy nhớ rằng group_concat_max_len mặc định là 1024 ký tự, vì vậy bạn nên xem xét việc thay đổi toàn cầu hoặc trong ứng dụng của bạn nếu bạn muốn nhiều hơn thế.

0

Bạn có thể mô phỏng các phân vùng row_number sử dụng các biến dùng và sau đó hạn chế dòng và áp dụng group_concat:

xem xét bảng sau:

create table your_table (
    id int primary key autoincrement, 
    category int, 
    value int 
); 

và dữ liệu:

insert into your_table (category, value) 
values 
(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 
(2, 6), (2, 7), (2, 8), (2, 9), (2, 10), 
(3, 11), (3, 12), (3, 13), (3, 14), (3, 15); 

Và chúng tôi muốn là giá trị 3 hàng đầu (theo thứ tự id mới nhất) cho mỗi danh mục được ghép nối:

select category, 
    group_concat(value order by id desc) as value_con 
from (
    select t.*, 
     @rn := if(@category = category, @rn + 1, if(@category := category,1, 1)) as seqnum 
    from your_table t 
    cross join (select @category := null, @rn := 0) x 
    order by t.category, t.id desc 
    ) t 
where seqnum <= 3 
group by category; 

Output:

category value_con 
1   5,4,3 
2   10,9,8 
3   15,14,13 

Đây là một demo về điều này.

Các vấn đề liên quan