如何使用find_in_set两个字符串匹配目标或任何东西?

时间:2014-03-06 09:31:43

标签: mysql

我有以下2个表。这里是模式Sqlfiddle

Table 1    
    Transaction  Items        
-----------  -------------
T1           I1,I3,I7     
T2           I7,I2,I3     
T3           I1,I2,I3     
T4           I2,I3        
T5           I2,I3,I4,I5  

Table 2 
    Id  Items   
------  --------
     1  I1,I3   
     2  I1,I2   
     3  I2,I4   
     4  I2,I3   
     5  I4,I5 

我希望Table 3中的每条记录都像Table2中的结果一样I1,I3,如第一行Table 1每个记录中SOT出现的时间。它应该显示在{ {1}}列作为答案。第一个是2

Table 3
    Id  Items      SOT  
------  ------  --------
     1  I1,I3          2
     2  I1,I2          1
     3  I2,I4          1
     4  I2,I3          4
     5  I4,I5          1
你可以告诉我这件事吗?我想到了find_in_set,但它仅适用于1字符串匹配。

1 个答案:

答案 0 :(得分:1)

作为演示,以下SQL将为您提供您想要的结果(我认为),Table2.Items中最多包含100个逗号分隔值。

正如你所看到的那样,阅读起来并不愉快,而且未来维持这种说法的任何人都可能会非常困惑。我不建议在实时代码中做这样的事情。

SELECT Id, COUNT(*)
FROM
(
    SELECT Transaction, anItemCount, ItemVal.Id, COUNT(anItem) AS aCount
    FROM
    (
        SELECT DISTINCT Id, SUBSTRING_INDEX(SUBSTRING_INDEX(Items, ',', AnInt), ',', -1) AS anItem
        FROM Table2,
        (
            SELECT 1 + Units.i + Tens.i * 10 as AnInt
            FROM
            (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Units,
            (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Tens
        ) Ints
    ) ItemVal
    INNER JOIN
    (
        SELECT Id, COUNT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(Items, ',', AnInt), ',', -1)) AS anItemCount
        FROM Table2,
        (
            SELECT 1 + Units.i + Tens.i * 10 as AnInt
            FROM
            (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Units,
            (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) Tens
        ) Ints
        GROUP BY Id
    ) ItemCnt
    ON ItemVal.Id = ItemCnt.Id
    INNER JOIN Table1
    ON FIND_IN_SET(ItemVal.anItem, Table1.Items)
    GROUP BY Transaction, anItemCount, ItemVal.Id
    HAVING anItemCount = aCount
) Sub1
GROUP BY Id

如果Table2.Items只包含2个值,则可以将其缩减为: -

SELECT Id, COUNT(*)
FROM
(
    SELECT Table1.Transaction, ItemVal.Id, COUNT(anItem) AS aCount
    FROM
    (
        SELECT Id, SUBSTRING_INDEX(Items, ',', 1) AS anItem
        FROM Table2
        UNION
        SELECT Id, SUBSTRING_INDEX(Items, ',', -1) AS anItem
        FROM Table2
    ) ItemVal
    INNER JOIN Table1
    ON FIND_IN_SET(ItemVal.anItem, Table1.Items)
    GROUP BY Table1.Transaction, ItemVal.Id
    HAVING aCount = 2
) Sub1
GROUP BY Id;

当Table2.Items中只有2个值时,它也可以简单地完成: -

SELECT Table2.Id, COUNT(Table1.Transaction) AS aCount
FROM Table2 
INNER JOIN Table1
ON FIND_IN_SET(SUBSTRING_INDEX(Table2.Items, ',', 1), Table1.Items)
AND FIND_IN_SET(SUBSTRING_INDEX(Table2.Items, ',', -1), Table1.Items)
GROUP BY Table2.Id

但仍然不愉快。

SQL小提琴: -

http://www.sqlfiddle.com/#!2/03fe9/19