MySql - FIND_IN_SET检查是否全部存在

时间:2014-08-07 16:02:25

标签: php mysql

我想检查mysql是否所有给定的密钥都存在于set中。像:

    $comma_separted_user_ids = "20,2,9,8,31,1";

    $query ="SELECT conversation_id FROM message 
             WHERE FIND_IN_SET($comma_separted_user_ids, user_ids) ";

    // data of user_ids = "1,2,8,9,20,31";

我想检查user_ids列中是否存在所有用户ID,user_ids未正确订购。

请提出解决方案,谢谢。

4 个答案:

答案 0 :(得分:2)

虽然技术上可行:

$query = 
  'SELECT conversation_id FROM message'
  . 'WHERE FIND_IN_SET(' 
  . str_replace(
      ',',
      ', user_ids) AND FIND_IN_SET('
      $comma_separted_user_ids
  )
  . ', user_ids)' ;

... 你永远不应该这样做!

而是创建一个新表来模拟usermessage实体之间存在的多对多关系(例如participant)。这是basic normalisation

然后查询变得微不足道性能:

SELECT conversation_id FROM participant
WHERE user_id IN ($comma_separted_user_ids)
GROUP BY conversation_id
HAVING COUNT(user_id) = [number of items in $comma_separted_user_ids]

答案 1 :(得分:1)

由于您不知道订购,我看不到FIND_IN_SET的方法。与others said一样,规范化表格结构要好得多。

但为了提供问题的答案,您需要创建一个FIND_IN_SET运营商列表。

// A list of IDs.
$comma_separated_user_ids = "20,2,9,8,31,1";

// The TRUE string will make sure that the array 
// always contains at least one item.
$where = array("TRUE");

// Iterate over the IDs and create strings such as
// "FIND_IN_SET(1, column_name_here)"
foreach(explode(",", $comma_separated_user_ids) as $id) {
    $where[] = "FIND_IN_SET($id, user_ids)";
}

然后将字符串连接在一起很简单:

// Join everything together with AND (&&).
// Since "0" is considered FALSE, this works.
$where = implode(" && ", $where);

// Query for rows.
$query ="SELECT conversation_id FROM message WHERE ($where) ";

如果您不需要,请不要使用此功能。它不会很好地扩展。

答案 2 :(得分:1)

你可以这样做:

SELECT conversation_id
FROM message 
WHERE FIND_IN_SET($comma_separted_user_ids, user_ids) > 0
GROUP BY conversation_id
HAVING count(distinct user_id) = 1 + (length($comma_separted_user_id) - length(replace($comma_separted_user_id, ',', '')))

having子句计算逗号分隔列表中的元素数。

如果要创建SQL,则应考虑使用表来存储值而不是列表。 join方法可以利用索引,find_in_set()不能。

答案 3 :(得分:-1)

我猜你应该这样写:

$comma_separted_user_ids = "20,2,9,8,31,1";

    $query ="SELECT conversation_id FROM message 
             WHERE user_id IN ($comma_separted_user_ids) ";