【问题标题】:Select items from a list using wildcards使用通配符从列表中选择项目
【发布时间】:2014-02-09 11:37:39
【问题描述】:

我有一个orders 表,其中包含与每个订单相关的items

id   | ... |  items
-----+-----+-----------------
34   | ... |  823, 27, 1657
678  | ... |  957
2548 | ... |  92, 823

字段orders.items 将内容存储为以逗号分隔的id 的文本字段。 (我知道设计是错误的,应该有一个一对多的表来链接订单和商品,但我没有设计它。

我需要根据订单中包含的商品选择订单

SELECT id, items FROM orders
WHERE items LIKE IN (
    SELECT CONCAT('%',id,'%') FROM items
    WHERE wishlist = 0

但显然它不起作用,因为我不能在从IN 获得的项目列表中使用LIKE。 但是,这正是我需要的,因为我需要使用 % 通配符来查找它们。

我怎样才能做到这一点?

编辑

在这个 SQL Fiddle 中有一个我的代码示例返回 7 行并缺少其中 2 行,其中 FIND_IN_LIST 函数具有完全相同的效果关于结果。

【问题讨论】:

  • order 是 MySQL 中的保留字,因此,正如所写,此查询在任何情况下都不起作用。但从根本上说,您的问题是标准化(或缺乏标准化)之一。 FIND_IN_SET 会做你想做的事,但它不能替代正确规范化的数据库。
  • 我选择“订单”这个名字只是为了说明——你是对的,我选错了。但是,这不是我在项目中使用的名称。
  • 你的字符串中总是有 3 个项目吗?
  • @Mihai 不,这只是一个例子。可以是1,可以是2,可以是N...
  • 这真的很难,你需要一个 mysql 的爆炸函数。我认为你会更好地进行规范化。

标签: mysql sql select concat


【解决方案1】:

试试这个:

SELECT DISTINCT o.id, o.items 
FROM orders AS o
INNER JOIN items AS i ON FIND_IN_SET(i.id, REPLACE(o.items, ' ', ''))
WHERE i.wishlist = 0 AND i.cost = 44800;

查看SQL FIDDLE DEMO

输出

|  ID |      ITEMS |
|-----|------------|
| 154 |   375, 374 |
| 155 |        377 |
| 159 |        384 |
| 172 |        435 |
| 174 |        440 |
| 228 |   770, 769 |
| 229 |    775,841 |
| 230 |        777 |
| 528 | 1518, 1517 |

【讨论】:

  • 我实际上得到了相同的结果,就好像我只使用普通的IN 而没有CONCAT...返回的结果是正确的,但是仍然缺少结果;并非所有结果都被返回。
  • 根据您对问题的描述,这应该可以工作(除了它会为每个项目、每个订单带回一行 - 很容易修复)。您能否发布一个表的 SQL 小提琴和一些演示该问题的测试数据?
  • @Kickstart 正如您在sqlfiddle.com/#!2/ffb8b/3/1 中看到的那样,这两种方法(我的方法和此答案中提出的方法)都返回 7 行,结果中仍然缺少 2 行。
  • @Jago - 这个解决方案没有返回几个订单行的原因是因为在一些逗号分隔的项目 ID 列表中的逗号后有随机空格。删除空格(或按照此处建议进行替换)并将行带回。
【解决方案2】:
SELECT id, items FROM `order` WHERE id REGEXP REPLACE(items,',','|');

SQL Fiddle

这使得它成为这样,基本上是LIKE的高级版本,'|'是为了或

select id, items FROM test WHERE id REGEXP '823|167|398';

【讨论】:

  • 我不太清楚如何将这个REGEXP REPLACE 函数应用到我的代码中...您能否根据我在sqlfiddle.com/#!2/ffb8b/3/1 上的代码进行详细说明?
猜你喜欢
  • 2016-03-27
  • 2014-04-06
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多