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

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

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

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

我的场地选择

  1. $venue = $result['venue'];

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

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

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

b09cbbtk

b09cbbtk1#

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

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

而是这样做:

  1. $venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$result['venue'])))));
  2. $sql = "SELECT * FROM venue WHERE id IN (".$venue.")";

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

  1. $v="1,,2 , 4); DROP TABLE users --";
  2. echo "Unsafe:\n";
  3. echo "SELECT * FROM venue WHERE id IN ({$v})\n\n";
  4. $venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$v)))));
  5. print_r($venue);
  6. echo "Safer:\n";
  7. echo "SELECT * FROM venue WHERE id IN ({$venue})\n\n";

输出

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

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

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

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

  1. //table customers_venues
  2. customer_id
  3. venue_id

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

  1. Select
  2. cv.venue
  3. from
  4. customers AS c
  5. JOIN
  6. customers_venues AS cv ON cv.customer_id = c.id
  7. JOIN
  8. venues as v ON cv.venue_id = v.id

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

展开查看全部
q3aa0525

q3aa05252#

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

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

相关问题