理想解决方案:
您可以改为创建两个表来对其进行规范化。第一个表将存储id 和area。
Create Table area_master (area_id int auto_increment,
area varchar(32),
description varchar(32)
Primary Key(area_id));
Insert into area
(area, description)
Values ('areaA', 'Hi'),
('areaB', 'Hello'); -- add more rows as you need
第二个表将存储area_id(来自area_master 表的FK)、attribute、value、attribute_order:
Create Table area_fruits (id int auto_increment,
area_id int,
attribute varchar(32),
value varchar(32),
attribute_order int
Primary Key(id));
Insert into area_fruits
(area_id, attribute, value, attribute_order)
Values (1, 'fruit', 'apple', 1),
(2, 'fruit', 'banana', 1),
(2, 'fruit', 'apple', 3); -- add more rows as needed
现在,获取数据的查询将如下所示,您无需每次都更改它,因为您添加了新水果 :-)
SELECT am.id, am.area, am.description
FROM area_master AS am
JOIN area_fruits AS af ON af.area_id = am.area_id AND
af.attribute = 'fruit'
GROUP BY am.id, am.area, am.description
HAVING SUM(af.value IN ('apple', 'pear', 'melon')) = COUNT(*)
P.S:可以进行更多改进,例如添加Foreign Key constraints等。但我希望你能明白要点。
原问题:
- 使用
Where,我们只考虑至少一个水果列具有apple、pear 或melon 的行
- 现在,我们在
id 上执行Group By,并使用Having 忽略水果列不为空的行,它们的值不是
apple、pear 和 melon。
尝试以下方法:
SELECT id
FROM fruits
WHERE fruit1 IN ('apple', 'pear', 'melon') OR
fruit2 IN ('apple', 'pear', 'melon') OR
fruit3 IN ('apple', 'pear', 'melon')
GROUP BY id
HAVING SUM(fruit1 NOT IN ('apple', 'pear', 'melon') AND fruit1 <> '') = 0 AND
SUM(fruit2 NOT IN ('apple', 'pear', 'melon') AND fruit2 <> '') = 0 AND
SUM(fruit3 NOT IN ('apple', 'pear', 'melon') AND fruit3 <> '') = 0
P.S 这是一个糟糕的设计。只要您有 n 个相似的列,就应该考虑对其进行规范化。