MS Access IN 运算符不返回行

MS Access IN operator not returning rows

使用 MS Access 数据库(我知道),下面的查询

SELECT * FROM PageImage WHERE (PageImage.Rooms) In ('1');

当 'PageImage.Rooms' 列只有一个值如 1

时只有 returns 行

'PageImage.Rooms'列中实际存储的数据是逗号分隔的列表,如1,2,3作为字符串存储,但在这种情况下不会返回任何数据。

从上面的查询和参考下图,当我期望返回 341,342,343 时,只返回了第 342 行

IN 操作与执行扩展 OR 语句的操作相同,其中 SELECT * FROM PageImage WHERE (PageImage.Rooms) In ('1','2');

相同

SELECT * FROM PageImage WHERE PageImage.Rooms = '1' OR PageIMage.Rooms = '2';

处理部分匹配需要 LIKE 关键字,因此 SELECT * FROM PageImage WHERE PageImage.Rooms LIKE '*1*'; 将 return 任何在字段中任何位置有一个 1 的字段。

鉴于 PageImage.Rooms 存储了您在评论中指定的真正的逗号分隔列表(即它不是 Access 2007+ 多值字段),您确实造成了一些混乱。由于这个原因,包含这样一列的 table 是完全未规范化的(甚至不是第一范式)。查询和数据一致性问题是可以预料的。

像您这样对多对多关系建模的常用方法是使用单独的 table。然而,在这种情况下,由于 PageImage 实体除了其 Id 之外似乎没有其他数据,因此您可以在相同的 table 中执行此操作。无论哪种方式,无论哪种 table 模型,关系都应该为每个 (PageImage.Id, Room) 对有一个单独的行,并且这些对应该是 table.[=12= 的复合键]

根据您现在的结构,您似乎想要的查询可以这样实现:

SELECT * FROM PageImage
WHERE
  PageImage.Rooms = '1'
  OR PageImage.Rooms LIKE '*,1'
  OR PageImage.Rooms LIKE '1,*'
  OR PageImage.Rooms LIKE '*,1,*'
;

正如戈德·汤普森 (Gord Thompson) 观察到的那样,可以更简洁、更有效地表达,如

SELECT * FROM PageImage
WHERE (',' & PageImage.Rooms & ',') LIKE '*,1,*'
;

如您所知,如果您想在同一个查询中与多个房间号进行比较,情况会变得更糟。

底线:就数据库而言,包含逗号分隔列表的字符串只是字符串。

我决定废弃多值字符串字段并沿着创建映射的正确路线前进table