2013-07-26 47 views
2

在countcolumn比較逗號分隔值在MySQL和獲得匹配的輸出在MySQL比較兩個逗號分隔值,並獲得所述匹配計數

實施例:

id values 
1 1,2,3 
2 3 
3 1,3 

通過比較id爲1和2的輸出應是1

通過比較ID 2和3的輸出應爲1

通過比較ID 3和1的輸出應爲2

+0

在格式上'ID的表中可用這些值:value'而不是逗號分隔清單?如果是這樣會更簡單(請參閱http://stackoverflow.com/questions/10375414/compare-similarities-between-two-result-sets)。 如果您在'VARCHAR'中存儲逗號分隔的值列表,您的數據庫結構可能需要稍微改進。 –

+2

你想在mysql或PHP中進行比較嗎? –

+2

這與PHP有什麼關係?你能舉一個你要求的更好的例子嗎? –

回答

3

首先,你所列出的數據應該被存放在一個格式,其中數據庫中的每一行存儲單個id和單個value,即3元素列表將對應於3行。如果對你的結構做出了這樣的改變,那麼下面的答案將是相關的Compare similarities between two result sets

就目前來看,這裏有一個很好的MySQL函數,我把它們放在一起,可以用於你的目的。這需要2個參數,它們是逗號分隔的列表,並將返回列表1中的列表1中的元素數量。

這不會妨礙列表1中的重複ID在列表2中計數兩次即'1,1,2'和'1,2'會返回3的值),但如果你願意的話,你可以很容易地找出如何調整它。

要利用這一點,只是做

SELECT 
    countMatchingElements('3' , '1,3') AS testCase1 
    countMatchingElements('1,2,3' , '1,3') AS testCase2 
    countMatchingElements('3' , '1,2,3') AS testCase3; 

存儲的功能邏輯如下

CREATE DEFINER = `yourUserGoesHere`@`%` FUNCTION `countMatchingElements`(inFirstList VARCHAR(1000), inSecondList VARCHAR(1000)) 
RETURNS tinyint(3) unsigned 
    NO SQL 
    DETERMINISTIC 
    SQL SECURITY INVOKER 
BEGIN 
    DECLARE numReturn TINYINT UNSIGNED DEFAULT 0; 
    DECLARE idsInFirstList TINYINT UNSIGNED; 
    DECLARE currentListItem VARCHAR(255) DEFAULT ''; 
    DECLARE currentID TINYINT UNSIGNED; 

    SET idsInFirstList = (CHAR_LENGTH(inFirstList) + 1) - CHAR_LENGTH(REPLACE(inFirstList , ',' , '')); 
    SET currentID = 1; 

    -- Loop over inFirstList, and for each element that is in inSecondList increment numReturn 
    firstListLoop: REPEAT 

     SET currentListItem = SUBSTRING_INDEX(SUBSTRING_INDEX(inFirstList , ',' , currentID) , ',' , -1); 

     IF FIND_IN_SET(currentListItem , inSecondList) THEN 

      SET numReturn = numReturn + 1; 

     END IF; 

     SET currentID = currentID + 1; 

    UNTIL currentID > idsInFirstList 
    END REPEAT firstListLoop; 

    RETURN numReturn; 
END 
0

如果它是一個SET類型的列,你可能能夠使用&操作,然後BIT_COUNT():

BIT_COUNT(values1 & values2)