类似于LIKE,但是使用整数表示要检查的字符串

4
假设我有一个表(tableA),其中有一个名为Kwaliteit的列,它将保存一个int值(0, 1, 2, 3),表示一些字符串值。这些字符串值被序列化存储在另一个表(tableB)中,如下所示:
a:4:{i:0;s:4:"Goed";i:1;s:5:"Matig";i:2;s:6:"Slecht";i:3;s:12:"Afgeschreven";}

这将会生成一个PHP数组,类似于这样:
Array
(
    [0] => Goed
    [1] => Matig
    [2] => Slecht
    [3] => Afgeschreven
)

事情是这样的,我想要在Afgeschreven上进行筛选。所以我将其插入查询的LIKE部分,但这并不起作用,因为tableA中存在一个int而不是string
我该如何解决这个问题?我能否使用字符串值临时更改列值以执行过滤操作? 编辑 这里是tableA(Kist)的结构。
CREATE TABLE IF NOT EXISTS `Kist` (
  `idKist` int(11) NOT NULL AUTO_INCREMENT,
  `idKistType` int(11) NOT NULL,
  `Tag1` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `Tag2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `VisueelNr` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Bouwjaar` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `kwaliteit` tinyint(1) NOT NULL,
  `Actief` tinyint(1) NOT NULL,
  PRIMARY KEY (`idKist`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=982 ;

INSERT INTO `Kist` (`idKist`, `idKistType`, `Tag1`, `Tag2`, `VisueelNr`, `Bouwjaar`, `kwaliteit`, `Actief`) VALUES
(1, 1, '0086-1700-0000-0000-0000-371E', '0086-1700-0000-0000-0000-3868', '0', '', 3, 0),
(2, 1, '0086-1700-0000-0000-0000-413F', '0086-1700-0000-0000-0000-409A', '0', '', 0, 1);

并且 tableB (设置)

CREATE TABLE IF NOT EXISTS `Instellingen` (
  `idInstellingen` int(11) NOT NULL AUTO_INCREMENT,
  `Instelling` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
  `Waarde` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`idInstellingen`),
  UNIQUE KEY `Instelling_UNIQUE` (`Instelling`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=220 ;

INSERT INTO `Instellingen` (`idInstellingen`, `Instelling`, `Waarde`) VALUES
(200, 'kistKwaliteit', 'a:4:{i:0;s:4:"Goed";i:1;s:5:"Matig";i:2;s:6:"Slecht";i:3;s:12:"Afgeschreven";}');

序列化后的值存储在Waarde列中。

我不太确定你想要过滤什么。你能发一些样本数据,以便你可以应用筛选器吗?据我所知,如果你想知道哪些行有Afgeschreven,你应该在没有任何LIKE子句的情况下过滤Kwaliteit=3。看到一些样本数据可能有助于澄清你想要找到的内容。 - Oldskool
@MatBailie 如果我表达不够清晰,抱歉。在tableA中,我有这些代表存储在tableB中的字符串整数。我想用一个字符串tableA上进行过滤。 - Mathlight
我们为什么要劝说人们规范化他们的数据库结构,而不是将json/序列化/逗号分隔的数据存储在列中呢?因为你必须读取json、解码它、确定你的输入表示哪个值,然后构建查询,这正是因为你通过不规范化消除了使用JOIN的选项。 - Mark Baker
@MarkBaker 同意。这就是那种情况。 - vitalii
@MarkBaker 我无法反驳这个观点!但与他人的决定合作总感觉有些困难...但也许如果不可能的话,我可以改变他们的意见... - Mathlight
显示剩余7条评论
3个回答

2

您所拥有的大致是这样的:

select * from tablea where kwaliteit = 'Afgeschreven';

这个不起作用,因为 kwaliteit 是代码,而不是字符串。你要找的是这个:

select * from tablea where kwaliteit =
 (select kwaliteit from tableb where text = 'Afgeschreven');

抱歉如果我没有表达清楚。我已经更新了问题,并附上了一些数据库数据。这将显示目前无法实现(除非我们要创建一个新的表)。 - Mathlight
好的。你能制作这个表格吗?MariaDB通过NoSQL增强了关系模型。然而,这不应该导致忽视关系数据库管理系统提供的基本功能。在使用代码时,应该有一个查找表和一个外键约束。 - Thorsten Kettner
尽管如此:您确实拥有要在表中过滤数据的值“Afgeschreven”。但是,为什么您只有这个字符串,而没有字符串的代码呢?当用户选择“Afgeschreven”时,您的应用程序应该知道这是代码3,并使用它来构建查询。 - Thorsten Kettner
我认为制作表格是这样的...用户将在文本框中填写筛选条件。因此,它也可以是“Af”或完全不相关的内容,只是因为在其他列上进行了筛选... - Mathlight
好的。那就建立那张表格,然后将 SQL 更改为类似于 select * from tablea where kwaliteit in (select kwaliteit from tableb where text like @search);。或者如果你想要在结果中显示 kwaliteit 字符串,可以使用连接操作。 - Thorsten Kettner
谢谢您和我一起思考。虽然您的答案是正确的,但它并没有导致解决这个问题(感谢其他团队成员的决定...)。这就是为什么我接受了其他人的答案,尽管您的答案在未来可能会对人们有所帮助。 - Mathlight

1

由于您保存的int到字符串的映射是以文本序列化的kwaliteit值,因此无法基于MySQL中的文本/标签进行选择。

例如,您可以创建一个新表Kwaliteit,有2个列id和label。然后,您可以将该新表与Kist表JOIN ON Kist.kwaliteit = Kwaliteit.id WHERE label ='Afgeschreven'的where条件将与这些列名一起使用。

另一个可能性是更改Instellingen表:将Waarde列拆分为2个列id和value。这意味着该表中kwaliteit的4行:

(200, 'kistKwaliteit', '0', 'Goed'), 
(200, 'kistKwaliteit', '1', 'Matig'), 
(200, 'kistKwaliteit', '2', 'Slecht'), 
(200, 'kistKwaliteit', '3', 'Afgeschreven')

请求可能是:

SELECT * FROM Kist WHERE kwaliteit = 
(SELECT id FROM Instellingen WHERE Instelling = 'kistKwaliteit' AND value = 'Afgeschreven')

如果您想保持数据库结构不变,您需要在PHP端处理获取与所需质量匹配的ID。例如,如果它是用户可以通过下拉菜单选择的内容,请将值设置为序列化数组中保存的ID,并将标签仅用作标签。或者,在获取质量字符串时,首先从数据库中获取序列化数组以查找ID,然后在SELECT中使用该ID。

谢谢你的回答。那最后一部分让我从一个全新的角度来思考它... - Mathlight

-1

不行。你应该通过数组键(也称为3或2)进行搜索,这样还可以加快查询速度。

对于更新的结构,你可以尝试使用:

select * from Instellingen where Waarde like "%Afgeschreven%";


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接