MySQL选择具有匹配数组值的行

时间:2016-10-07 19:39:31

标签: mysql sql

我一直在寻找一些关于我如何选择数据库中的行的方法,其中一个数组将某些值与另一个表中的另一个数组相匹配。

我有一个名为" users"的表。在表格内部有一个名为" user_interests"包含一个有兴趣的数组。一个例子可能是"食物,时尚,音乐"作为一种价值。

在另一个名为" posts"包含一个名为" post_keywords"的列。使用另一个数组的值,例如" users"表

任何人都可以帮我找到选择符合用户兴趣的帖子的正确方法吗?到目前为止,我了解到我必须在MySQL查询中执行此操作。

提前致谢。

1 个答案:

答案 0 :(得分:1)

在我们回答所提出的问题之前,我们应该解决一个更重要的重要的问题:我们是否应该真正将值存储在逗号分隔的列表中。这是一个SQL反模式。

&lt;! - 在Bill Karwin的优秀大部分第2章中解释了特定的SQL反模式: SQL反模式:避免数据库编程的陷阱,可从许多优秀的书商那里获得,包括亚马逊< / p>

https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557

- &GT;

本章还讨论了一个更合适的SQL模式,将值存储为单独的,每个值都在自己的行上。这就是SQL设计为在行上运行的方式。

在考虑警告之后,如果您仍然需要在字符串中以逗号分隔的值列表中搜索值...

MySQL提供 FIND_IN_SET 函数,该函数将返回列表中值的位置

如果找到匹配值,该函数将返回一个正整数。

如果匹配的值 not ,则该函数将返回0.如果其中一个参数为NULL,则该函数将返回NULL。

作为函数如何工作的简单演示:

  SELECT FIND_IN_SET('bowling' ,'food,fashion,music')    -- > 0
       , FIND_IN_SET('food'    ,'food,fashion,music')    -- > 1
       , FIND_IN_SET('fashion' ,'food,fashion,music')    -- > 2
       , FIND_IN_SET('music'   ,'food,fashion,music')    -- > 3

为了在查询中使用它,MySQL允许我们在布尔上下文中使用表达式......

  SELECT t.id
    FROM my_table t
   WHERE FIND_IN_SET('food'  ,t.my_comma_separated_list_col)
     AND FIND_IN_SET('music' ,t.my_comma_separated_list_col)

这将返回my_table中具有my_comma_separated_list_col值的行,例如:

'food,music'
'bowling,dancing,food,music'
'music,food'

如果在列表中找到指定的搜索值(例如'food'),FIND_IN_SET将返回一个正整数,在布尔上下文中计算结果为TRUE。

如果在列表中找不到指定的值,FIND_IN_SET将返回0,其值为FALSE。

返回NULL只是一个NULL,既不是TRUE也不是FALSE。

备注:

NULL值将导致FIND_IN_SET返回NULL。

SELECT FIND_IN_SET(NULL  ,NULL)                        -- > NULL
     , FIND_IN_SET(NULL  ,'food,fashion,music')        -- > NULL 
     , FIND_IN_SET('food',NULL)                        -- > NULL

列表中的值中的前导空格和尾随空格,或者找不到要搜索的值。除非搜索值和列表值都是精确匹配,包括前导和尾随空格。 (所以,不要在列表中的值之间使用任何空格):

值列表中的前导和/或尾随空格导致“未找到”

SELECT FIND_IN_SET('bowling'  ,' food, fashion, music') -- > 0
     , FIND_IN_SET('food'     ,' food, fashion, music') -- > 0 !
     , FIND_IN_SET('fashion'  ,' food, fashion, music') -- > 0 !
     , FIND_IN_SET('music'    ,' food, fashion, music') -- > 0 !
;    
SELECT FIND_IN_SET('bowling'  ,'food ,fashion ,music ') -- > 0
     , FIND_IN_SET('food'     ,'food ,fashion ,music ') -- > 0 !
     , FIND_IN_SET('fashion'  ,'food ,fashion ,music ') -- > 0 !
     , FIND_IN_SET('music'    ,'food ,fashion ,music ') -- > 0 !
;

值中的前导或尾随空格会导致“找不到”

SELECT FIND_IN_SET('bowling'  ,'food,fashion,music')    -- > 0
     , FIND_IN_SET('food '    ,'food,fashion,music')    -- > 0 !
     , FIND_IN_SET(' fashion' ,'food,fashion,music')    -- > 0 !
     , FIND_IN_SET(' music '  ,'food,fashion,music')    -- > 0 !
;