MySQL DISTINCT trên GROUP_CONCAT ()


183

Tôi đang làm SELECT GROUP_CONCAT(categories SEPARATOR ' ') FROM table. Dữ liệu mẫu dưới đây:

categories
----------
test1 test2 test3
test4
test1 test3
test1 test3

Tuy nhiên, tôi đang test1 test2 test3 test4 test1 test3quay trở lại và tôi muốn test1 test2 test3 test4quay lại. Có ý kiến ​​gì không?

Cảm ơn nhiều!

Câu trả lời:


361

GROUP_CONCAT có thuộc tính DISTINCT:

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ') FROM table

48

Sử dụng DISTINCT sẽ hoạt động

SELECT GROUP_CONCAT(DISTINCT(categories) SEPARATOR ' ') FROM table

REf: - cái này


19

DISTINCT: sẽ cung cấp cho bạn các giá trị duy nhất.

SELECT GROUP_CONCAT(DISTINCT(categories )) AS categories FROM table

17

Các câu trả lời khác cho câu hỏi này không trả về những gì OP cần, họ sẽ trả về một chuỗi như:

test1 test2 test3 test1 test3 test4

(lưu ý rằng test1test3được nhân đôi) trong khi OP muốn trả về chuỗi này:

test1 test2 test3 test4

vấn đề ở đây là chuỗi "test1 test3"được sao chép và chỉ được chèn một lần, nhưng tất cả các chuỗi khác là khác biệt với nhau ( "test1 test2 test3"khác biệt hơn "test1 test3", ngay cả khi một số thử nghiệm có trong toàn bộ chuỗi được sao chép).

Điều chúng ta cần làm ở đây là chia mỗi chuỗi thành các hàng khác nhau và trước tiên chúng ta cần tạo một bảng số:

CREATE TABLE numbers (n INT);
INSERT INTO numbers VALUES
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

sau đó chúng ta có thể chạy truy vấn này:

SELECT
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(tableName.categories, ' ', numbers.n),
    ' ',
    -1) category
FROM
  numbers INNER JOIN tableName
  ON
    LENGTH(tableName.categories)>=
    LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1;

và chúng tôi nhận được một kết quả như thế này:

test1
test4
test1
test1
test2
test3
test3
test3

và sau đó chúng ta có thể áp dụng hàm tổng hợp GROUP_CONCAT, sử dụng mệnh đề DISTINCT:

SELECT
  GROUP_CONCAT(DISTINCT category ORDER BY category SEPARATOR ' ')
FROM (
  SELECT
    SUBSTRING_INDEX(SUBSTRING_INDEX(tableName.categories, ' ', numbers.n), ' ', -1) category
  FROM
    numbers INNER JOIN tableName
    ON LENGTH(tableName.categories)>=LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1
  ) s;

Xin vui lòng xem fiddle ở đây .


Có vẻ như cách giải thích của bạn về câu hỏi của OP có thể đúng; tuy nhiên, tôi nghĩ cần chỉ ra rằng việc bình thường hóa dữ liệu bằng cách tạo bảng "blah_to_clists" và bảng "danh mục" cho mối quan hệ nhiều-nhiều thích hợp sẽ là cách thực hành tốt nhất ở đây và sẽ thêm linh hoạt. Tuy nhiên, câu trả lời của bạn là một cách giải quyết thông minh cho bất kỳ ai thừa hưởng một lược đồ không chuẩn hóa như vậy. Nó cũng có thể được điều chỉnh cho mục đích tạo ra sự di chuyển từ lược đồ cũ sang lược đồ chuẩn hóa.
XP84

11
SELECT
  GROUP_CONCAT(DISTINCT (category))
FROM (
  SELECT
    SUBSTRING_INDEX(SUBSTRING_INDEX(tableName.categories, ' ', numbers.n), ' ', -1) category
  FROM
    numbers INNER JOIN tableName
    ON LENGTH(tableName.categories)>=LENGTH(REPLACE(tableName.categories, ' ', ''))+numbers.n-1
  ) s;   

Điều này sẽ trả về các giá trị riêng biệt như: test1, test2, test4, test3


5

Bạn chỉ có thể thêm DISTINCT ở phía trước.

SELECT GROUP_CONCAT(DISTINCT categories SEPARATOR ' ')

nếu bạn muốn sắp xếp

SELECT GROUP_CONCAT(DISTINCT categories ORDER BY categories ASC SEPARATOR ' ')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.