mysql-如何在一个表中选择id值位于另一个表中逗号分隔字段中的行?

6qqygrtg  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(428)

我已经研究这个问题三天了,眼睛都睁不开了。我有一个sql“customers”表,其中包含客户姓名、地址、电子邮件和一个名为“venue”的字段,其中包含一组逗号分隔的“id”,表示他们感兴趣的培训课程的地点(比如:18,22,35,41)
我还有一张table叫“场地”,里面有所有课程的场地。每个课程在“地点”表中是一个单独的行,具有自动递增的id。“客户”表中的“地点”字段是“地点”表中客户在注册时选择的行“id”的集合。
一旦客户注册并被传送到“我的兴趣”页面,我想通过输出客户表的“customer.venture”字段中保存的“venture”表的每个“id”的行数据来显示他们注册感兴趣的课程。
我希望这有道理。。。
我的客户选择

$sqlc = "Select * from customers ORDER BY id DESC LIMIT 1";

我的场地选择

$venue = $result['venue'];

我当前的“地点”选择代码不起作用

sqlcp = "SELECT * FROM venue WHERE FIND_IN_SET('$venue', id)";

请询问任何需要的问题,谢谢您的关注

b09cbbtk

b09cbbtk1#

除非我误解了这个问题:
名为“地点”的字段[输入],包含逗号分隔的集合
换句话说,我们可以说 $result['venue'] 就像 1,2,3,4 .
然后这一点:
我还有一张table叫“场地”,里面有所有课程的场地。每道菜都是单独的一排
换句话说,我们可以这么说 id 是场地的主键。
因此,您的输入似乎是分隔的列表,并且您的表具有正确的ID。为此,我们只能 IN 并提供一个ID列表。
当然,在这种情况下,您可以将它们插入到查询中(id不需要引号),但这根本不提供故障保护。
例如:

//Please don't do this as you can get SQLInjection from the input
  $sql = "SELECT * FROM venue WHERE id IN (".$result['venue'].")";

而是这样做:

$venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$result['venue'])))));

   $sql = "SELECT * FROM venue WHERE id IN (".$venue.")";

通常我不会连接,但请注意 array_map('intval', ..) 将它们转换为整数。
要解释所有这些对数组的影响(按顺序):
爆炸 , 修剪空白,例如 , 逗号空格将留下空白
过滤器将删除任何虚假元素,如 ,, 空纸条 0 是其中一部分吗
将类型转换为 int 有几个原因。
然后我们再次内爆它。
这似乎有点多余,但它会清除用户提供的输入。例如,考虑以下因素:

$v="1,,2 , 4); DROP TABLE users --";

 echo "Unsafe:\n";
 echo "SELECT * FROM venue WHERE id IN ({$v})\n\n";

 $venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$v)))));

 print_r($venue);

 echo "Safer:\n";
 echo "SELECT * FROM venue WHERE id IN ({$venue})\n\n";

输出

Unsafe:
 SELECT * FROM venue WHERE id IN (1,,2 , 4); DROP TABLE users --)

 Safer:
 SELECT * FROM venue WHERE id IN (1,2,4)

沙箱
p、 mutli查询注入在“现代”版本的php中可能无论如何都不起作用,但这只是一个例子
在性能方面,这将是更好的,因为它可以使用适当的指标在会场。
我觉得你把事情复杂化了。
@塔哈·阿斯加里是对的,你的论点是相反的。这是一个很容易的错误,因为它的目的是在数据库中查找列表中的内容。而不是相反,至少这是常用的使用方法。
例如:

//this is the correct way
     SELECT * FROM venue WHERE FIND_IN_SET(1,'1,2,3,4')
     //this is the way you have it
     SELECT * FROM venue WHERE FIND_IN_SET('1,2,3,4', 1)

在\集合中查找\以供参考
也就是说,我们不需要使用 FIND_IN_SET 在这个例子中,因为我们可以只使用in,在这个例子中哪个更“合适”。
最后一件事是,如果这些存储在一个单独的表中,并且与客户有关系,那么您可以在mysql中完成这一切。数据库中的csv数据通常效果不佳。您只需要一个有两列的表。

//table customers_venues
  customer_id
  venue_id

然后您可以执行如下查询:

Select 
        cv.venue
    from
        customers AS c
    JOIN
        customers_venues AS cv ON cv.customer_id = c.id
    JOIN
        venues as v ON cv.venue_id = v.id

但我不知道该说些什么 LIMIT 1 .
干杯!

q3aa0525

q3aa05252#

我认为你应该这样写代码:

$sqlcp = "SELECT * FROM venue WHERE FIND_IN_SET(id,'$venue')";

相关问题