2010-06-26 32 views
10

Tôi muốn so sánh các từ riêng lẻ từ đầu vào của người dùng với các từ riêng lẻ từ một cột trong bảng của tôi.SQL: Tách một cột thành nhiều từ để tìm kiếm người dùng nhập

Ví dụ, hãy xem xét các hàng trong bảng của tôi:

ID Name 
1 Jack Nicholson 
2 Henry Jack Blueberry 
3 Pontiac Riddleson Jack 

Hãy xem xét rằng đầu vào của người dùng là 'Pontiac Jack'. Tôi muốn gán trọng số/xếp hạng cho mỗi trận đấu, vì vậy tôi không thể sử dụng một tấm chăn LIKE (WHERE Name LIKE @SearchString).

Nếu Pontiac có mặt trong bất kỳ hàng nào, tôi muốn trao 10 điểm. Mỗi trận đấu cho Jack được 10 điểm khác, v.v. Vì vậy, hàng 3 sẽ nhận được 20 điểm, và hàng 1 và 2 nhận được 10.

Tôi đã chia đầu vào của người dùng thành từng từ và lưu chúng vào bảng tạm thời @SearchWords (Word).

Nhưng tôi không thể tìm ra cách để có câu lệnh SELECT cho phép tôi kết hợp điều này. Có lẽ tôi đang đi về điều này một cách sai lầm?

Chúc mừng, WT

+1

bạn có cân nhắc sử dụng tìm kiếm SQL SErver Fulltext không? –

+0

Có, tôi có - nó không hoạt động tốt cho chúng tôi, và rất khó để tùy chỉnh nó theo yêu cầu của chúng tôi. –

+1

+1 cho tìm kiếm toàn văn - không nhất thiết là SQL Server nhưng ví dụ lucene.net. –

Trả lời

1

Đối với SQL Server, hãy thử này:

SELECT Word, COUNT(Word) * 10 AS WordCount 
FROM SourceTable 
INNER JOIN SearchWords ON CHARINDEX(SearchWords.Word, SourceTable.Name) > 0 
GROUP BY Word 
+0

Giải pháp đẹp, thanh lịch. Tôi hình dung bảng của OP sẽ có thứ gì đó liên kết các từ riêng lẻ với cụm từ tìm kiếm ban đầu - vì vậy nhận được điểm cho toàn bộ cụm từ sẽ đơn giản như tham gia cụm từ này và tổng số từ được nhóm theo toàn bộ cụm từ. Tên người dùng btw đẹp ...một trong những xkcd yêu thích của tôi :) –

0

Điều gì về điều này? (Đây là cú pháp MySQL, tôi nghĩ rằng bạn chỉ cần thay thế các CONCAT và làm điều đó với +)

SELECT names.id, count(searchwords.word) FROM names, searchwords WHERE names.name LIKE CONCAT('%', searchwords.word, '%') GROUP BY names.id 

Sau đó, bạn sẽ có một kết quả SQL với ID của tên-bàn và đếm các từ phù hợp với id đó.

0

Bạn có thể làm điều đó thông qua một biểu bảng phổ biến mà các công trình ra các trọng số. Ví dụ:

--** Set up the example tables and data 
DECLARE @Name TABLE (id INT IDENTITY, name VARCHAR(50)); 
DECLARE @SearchWords TABLE (word VARCHAR(50)); 

INSERT INTO @Name 
     (name) 
VALUES ('Jack Nicholson') 
     ,('Henry Jack Blueberry') 
     ,('Pontiac Riddleson Jack') 
     ,('Fred Bloggs'); 

INSERT INTO @SearchWords 
     (word) 
VALUES ('Jack') 
     ,('Pontiac'); 

--** Example SELECT with @Name selected and ordered by words in @SearchWords 
WITH Order_CTE (weighting, id) 
AS (
    SELECT COUNT(*) AS weighting 
     , id 
     FROM @Name AS n 
     JOIN @SearchWords AS sw 
     ON n.name LIKE '%' + sw.word + '%' 
    GROUP BY id 
) 
SELECT n.name 
    , cte.weighting 
    FROM @Name AS n 
    JOIN Order_CTE AS cte 
    ON n.id = cte.id 
ORDER BY cte.weighting DESC; 

Sử dụng kỹ thuật này, bạn cũng có thể áp dụng giá trị cho từng từ tìm kiếm nếu bạn muốn. Vì vậy, bạn có thể làm cho Jack có giá trị hơn Pontiac. Điều này sẽ trông giống như sau:

--** Set up the example tables and data 
DECLARE @Name TABLE (id INT IDENTITY, name VARCHAR(50)); 
DECLARE @SearchWords TABLE (word VARCHAR(50), value INT); 

INSERT INTO @Name 
     (name) 
VALUES ('Jack Nicholson') 
     ,('Henry Jack Blueberry') 
     ,('Pontiac Riddleson Jack') 
     ,('Fred Bloggs'); 

--** Set up search words with associated value 
INSERT INTO @SearchWords 
     (word, value) 
VALUES ('Jack',10) 
     ,('Pontiac',20) 
     ,('Bloggs',40); 


--** Example SELECT with @Name selected and ordered by words and values in @SearchWords 
WITH Order_CTE (weighting, id) 
AS (
    SELECT SUM(sw.value) AS weighting 
     , id 
     FROM @Name AS n 
     JOIN @SearchWords AS sw 
     ON n.name LIKE '%' + sw.word + '%' 
    GROUP BY id 
) 
SELECT n.name 
    , cte.weighting 
    FROM @Name AS n 
    JOIN Order_CTE AS cte 
    ON n.id = cte.id 
ORDER BY cte.weighting DESC;  
0

Dường như với tôi điều tốt nhất cần làm là duy trì một bảng riêng biệt với tất cả các từ riêng lẻ. Ví dụ:

ID  Word  FK_ID 
1  Jack  1 
2  Nicholson 1 
3  Henry  2 
(etc) 

Bảng này sẽ được cập nhật với trình kích hoạt và bạn có chỉ mục không nhóm trên 'Word', 'FK_ID'. Sau đó, SQL để tạo ra trọng số của bạn sẽ đơn giản và hiệu quả.

0

Làm thế nào về một cái gì đó như thế này ....

Select id, MAX(names.name), count(id)*10 from names 
inner join @SearchWords as sw on 
    names.name like '%'+sw.word+'%' 
group by id 

giả định rằng bảng với tên gọi là "tên".

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