2011-08-11 73 views
13

Vì vậy, câu hỏi của tôi là khá đơn giản:Làm thế nào để đếm các mục trong dấu phẩy danh sách tách MySQL

Tôi có một cột trong SQL mà là một danh sách dấu phẩy tách ra (ví dụ cats,dogs,cows,) Tôi cần phải đếm số lượng các mặt hàng trong đó sử dụng chỉ sql (vì vậy bất cứ chức năng của tôi là (cho phép gọi nó là fx cho bây giờ) sẽ làm việc như thế này:

SELECT fx(fooCommaDelimColumn) AS listCount FROM table WHERE id=... 

tôi biết rằng đó là sai lầm, nhưng bạn sẽ có được ý tưởng (BTW nếu giá trị của fooCommaDelimColumncats,dogs,cows,, sau đó listCount phải trả về 4 ...).

Đó là tất cả.

+0

chủ đề này cũng đã được trả lời qua [ở đây] (https: // stackoverflow.com/questions/5033047/mysql-query-finding-values-in-a-dấu phẩy-chuỗi/47069224 # 47069224) – Delickate

Trả lời

38

Không có tích hợp chức năng mà đếm lần xuất hiện của chuỗi con trong một chuỗi, nhưng bạn có thể tính toán sự khác biệt giữa các chuỗi ban đầu, và cùng một chuỗi mà không cần dấu phẩy:

LENGTH(fooCommaDelimColumn) - LENGTH(REPLACE(fooCommaDelimColumn, ',', '')) 
+0

Mặc dù điều này có hiệu quả, nhưng có thể nói rằng Tomas sẽ không gặp vấn đề này nếu anh ta đã đúng mô hình hóa là cơ sở dữ liệu. –

+6

Thực ra bạn nên thêm 1 vào câu trả lời của bạn trong trường hợp chỉ có một mục trong danh sách: LENGTH (fooCommaDelimColumn) - LENGTH (REPLACE (fooCommaDelimColumn, ',', '')) + 1. Điều này vẫn xứng đáng là +1 cho nguyên tắc thể hiện. – RolandoMySQLDBA

+0

@RolandoMySQLDBA: Tôi cũng nghĩ tương tự, nhưng chuỗi của Tomas bao gồm dấu phẩy, vì vậy không cần thiết. –

6

giải pháp zerkms 'hoạt động, không nghi ngờ gì về điều đó. Nhưng vấn đề của bạn được tạo ra bởi một lược đồ cơ sở dữ liệu không chính xác, như Steve Wellens đã chỉ ra. Bạn không nên có nhiều hơn một giá trị trong một cột vì nó vi phạm luật bình thường đầu tiên. Thay vào đó, bạn nên tạo ít nhất hai bảng. Ví dụ, giả sử rằng bạn có thành viên người sở hữu động vật:

table member (member_id, member_name) 
table member_animal (member_id, animal_name) 

Thậm chí tốt hơn: vì nhiều người dùng có thể có cùng một loại động vật, bạn nên tạo 3 bảng:

table member (member_id, member_name) 
table animal (animal_id, animal_name) 
table member_animal (member_id, animal_id) 

Bạn có thể điền các bảng như thế này, ví dụ:

member (1, 'Tomas') 
member (2, 'Vincent') 
animal (1, 'cat') 
animal (2, 'dog') 
animal (3, 'turtle') 
member_animal (1, 1) 
member_animal (1, 3) 
member_animal (2, 2) 
member_animal (2, 3) 

Và, để trả lời câu hỏi ban đầu, đây là những gì bạn sẽ làm nếu bạn muốn biết số lượng động vật mà mỗi người dùng có:

SELECT member_id, COUNT(*) AS num_animals 
FROM member 
INNER JOIN member_animal 
    USING (member_id) 
INNER JOIN animal 
    USING (animal_id) 
GROUP BY member_id; 
+0

Thực tế câu trả lời này chính xác hơn *. Tại SO chúng tôi giúp đỡ lẫn nhau để thực hiện một cách chính xác, để giải quyết gốc rễ của các vấn đề, +1 – zerkms

+0

Cảm ơn sự giúp đỡ, tôi vẫn muốn có được một số tài nguyên học tập (như bạn có thể thấy kiến thức sql của tôi kết thúc bằng UPDATE :)) – Tomas

4

Làm theo đề xuất từ ​​@zerkms.

Nếu bạn không biết nếu có một dấu phẩy dấu hay không, sử dụng chức năng TRIM để loại bỏ bất kỳ dấu phẩy trailing:

(
    LENGTH(TRIM(BOTH ',' FROM fooCommaDelimColumn)) 
    - LENGTH(REPLACE(TRIM(BOTH ',' FROM fooCommaDelimColumn), ',', '')) 
    + 1 
) as count 

tham khảo: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_trim

Tôi cũng đồng ý rằng một refactoring các bảng là tùy chọn tốt nhất, nhưng nếu điều này là không thể bây giờ, đoạn mã này có thể thực hiện công việc.

+0

Đây là giải pháp toàn diện. Đôi khi cần lưu trữ dữ liệu (mảng) ở dạng mã hóa JSON (ví dụ: '[" ABC "," DEF "," GHI "," JKL "]') và chưa đếm các mục bên trong. Vì mục đích này, giải pháp của bạn hoạt động ngay cả khi không cắt xén *. – shadyyx

2

Phiên bản này không hỗ trợ dấu phẩy ở đầu hoặc cuối, nhưng hỗ trợ một giá trị rỗng với một số từ 0:

IF(values, LENGTH(values) - LENGTH(REPLACE(values, ',', '')) + 1, 0) AS values_count 
Các vấn đề liên quan