2012-11-02 21 views
6

Tôi đang cố gắng tìm hiểu cách xác định các từ được sử dụng nhiều nhất trên tập dữ liệu mysql.xác định tập hợp các từ được sử dụng nhiều nhất php mysql

Không chắc chắn cách thực hiện việc này hoặc nếu có cách tiếp cận đơn giản hơn. Đọc một vài bài đăng trong đó một số gợi ý một thuật toán.

Ví dụ:

Từ 24.500 bản ghi, tìm ra 10 từ được sử dụng hàng đầu.

+2

Bạn có đang phân tích dữ liệu từ một trường đơn lẻ với nhiều từ không? Một chút thông tin sẽ hữu ích. – Tom

+0

Có, một trường (cột) với nhiều chuỗi từ. – Codex73

+0

Tôi đã làm điều tương tự trong một tập lệnh php. Không chắc chắn tôi sẽ cố gắng làm điều đó trong một câu lệnh SQL đơn. Một vấn đề là chia cột thành các từ và trả về từng từ một hàng (tôi đã sử dụng cụm từ thông dụng cho điều này), nhưng sau đó xác định những gì bạn quan tâm như là sự ngắt quãng giữa các từ và cách bạn muốn xử lý số nhiều bạn muốn đối xử với họ như một từ hoặc 2 từ khác nhau). Có thể dễ nhất để viết một hàm MySQL để tách cột thành các từ, trả về nhiều hàng, sau đó sử dụng nó từ bên trong một số SQL để đếm hoặc xuất hiện. – Kickstart

Trả lời

13

Phải, điều này chạy như một con chó và bị giới hạn khi làm việc với một dấu tách đơn, nhưng hy vọng sẽ cung cấp cho bạn một ý tưởng.

SELECT aWord, COUNT(*) AS WordOccuranceCount 
FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(concat(SomeColumn, ' '), ' ', aCnt), ' ', -1) AS aWord 
FROM SomeTable 
CROSS JOIN (
SELECT a.i+b.i*10+c.i*100 + 1 AS aCnt 
FROM integers a, integers b, integers c) Sub1 
WHERE (LENGTH(SomeColumn) + 1 - LENGTH(REPLACE(SomeColumn, ' ', ''))) >= aCnt) Sub2 
WHERE Sub2.aWord != '' 
GROUP BY aWord 
ORDER BY WordOccuranceCount DESC 
LIMIT 10 

này dựa vào việc có một bảng gọi là số nguyên với một cột duy nhất gọi tôi với 10 dòng với các giá trị từ 0 đến 9. Nó phản ứng với lên đến ~ 1000 từ nhưng có thể dễ dàng được thay đổi để đối phó với hơn (nhưng sẽ làm chậm hơn nữa).

1

Ý tưởng chung là tìm ra số lượng dấu phân tách (ví dụ: dấu cách) trong mỗi trường và chạy SUBSTRING_INDEX() trong một vòng lặp, cho mỗi trường như vậy. Việc đưa nó vào một bảng tạm thời có thêm lợi ích khi có thể chạy điều này trong các khối, song song, vv Không nên quá cồng kềnh để ném một số SP với nhau để làm điều này.

+0

Hmm ... trông giống như [ai đó] (http://www.montrealseocompany.com/2012/04/17/mysql-split-string-into-rows-function/) đã gặp sự cố khi chuỗi này loại điều với nhau. – fenway

4

Tại sao không làm tất cả trong PHP? Bước sẽ

  1. Tạo một từ điển (word => count)
  2. đọc cho bạn dữ liệu trong PHP
  3. chia nó thành các từ
  4. Thêm từng từ vào từ điển (bạn có thể muốn thành chữ thường và cắt chúng đầu tiên)
  5. Nếu đã có trong từ điển, hãy tăng số lượng của nó. Nếu chưa có trong từ điển, thiết lập 1 là giá trị của nó (count = 1)
  6. Lặp lại các yếu tố từ điển của bạn để tìm ra 10 giá trị cao nhất

tôi sẽ không làm điều đó trong SQL chủ yếu là bởi vì nó muốn kết thúc lên phức tạp hơn.

+0

Tôi đề xuất phương pháp này, Bạn có thể thêm một số bộ lọc cho các từ thường được sử dụng như "is, was, the, a", v.v. Vì nếu bạn đếm số đếm một cách mù quáng từ cơ sở dữ liệu, bạn có thể kết thúc với các từ thường được sử dụng đầu danh sách. – Samy

+0

Nếu sử dụng tập lệnh thì có thể có nhiều ưu điểm. Không chỉ loại trừ các từ dừng phổ biến mà còn xử lý các dấu phân cách khác nhau, xóa dấu chấm câu, biến số nhiều thành chữ cái và có thể xử lý các từ đồng nghĩa và chữ viết tắt. Điều đó nói rằng các từ dừng phổ biến có thể được loại bỏ tương đối dễ dàng bằng cách sử dụng một giải pháp SQL thuần túy (chỉ cần có một bảng từ dừng, làm một trái tham gia vào bảng đó và loại trừ bất kỳ hàng nào có khớp). – Kickstart

0

Một chút cải thiện, loại bỏ từ dừng từ danh sách với VÀ Sub2.aWord không (danh sách các từ dừng)

SELECT aWord, COUNT(*) AS WordOccuranceCount 
FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(concat(txt_msg, ' '), ' ', aCnt), ' ', -1) AS aWord 
FROM mensagens 
CROSS JOIN (
SELECT a.i+b.i*10+c.i*100 + 1 AS aCnt 
FROM integers a, integers b, integers c) Sub1 
WHERE (LENGTH(txt_msg) + 1 - LENGTH(REPLACE(txt_msg, ' ', ''))) >= aCnt) Sub2 
WHERE Sub2.aWord != '' AND Sub2.aWord not in ('a','about','above', .....) 
GROUP BY aWord 
ORDER BY WordOccuranceCount DESC 
LIMIT 10 
1
SELECT `COLUMNNAME`, COUNT(*) FROM `TABLENAME` GROUP BY `COLUMNNAME` 

của nó rất đơn giản và làm việc ... :)

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