我整天都在努力解决某个问题,我决定寻求帮助。
我需要一个查询来检查整个表格行及其所有表格单元格的值是“是”'然后它需要给我这些列的名称。
通过一个例子澄清: 在上表中,我需要检查所有单元格的水果行,其值为“是”'并将相应的列名返回给我。在这种情况下,结果将是' banana' apple' apple'和'梨'。
我希望这个例子有所帮助。
-- pseudo code
SELECT `COLUMN_NAMES`
FROM `My_Table`
ROW `fruit`
WHERE `value` = 'yes';
我还要注意,我无法重新安排数据库。数据库结构无法更改,因为我们已经在进行SELECT' property'之类的查询。在哪里'香蕉' ='是'(这将返回'水果')。我也需要它以相反的方式工作。
答案 0 :(得分:1)
听起来你已经有了依赖于这个表结构的其他查询,但我仍然会认真考虑改变结构,即使它意味着重写一些查询。
我认为Barmar编写的查询可以帮助您获得所需内容。它看起来应该是这样,而且从我所看到的情况来看,对于带有SQL的Barmar来说,没有什么是不可能的。但请考虑此结构对您应用程序其余部分的影响。
如果您想添加商品怎么办? (像其他水果一样。)通常使用INSERT
查询将项目添加到数据库。在这种情况下,您必须使用ALTER TABLE
代替,并添加一列。完成此操作后,您还必须更改选择具有特定属性(您在此处询问的属性)的项的查询以包含新列。您必须在添加项目时更改应用程序代码,或者想出某种方式动态地包含查询中的每一列。
如果要选择具有多个属性的项目,该怎么办?显然没有很多液体水果,(除非你把它们放在冰箱里太长时间),但我认为这两种不是你将要拥有的唯一属性。 CONCAT方法将难以处理。我确信有办法解决它,但你真的只是解决一个问题,而不是修复它。
这些是几个例子,但是还有许多其他问题会使这个结构真正难以应对。
处理这样的多对多关系的一种不那么繁琐的方法是使用三个表。一个用于项目,一个用于属性,另一个用于将项目链接到其属性。像这样:
items properties item_properties
id item_name id name item_id property_id
1 banana 1 fruit 1 1
2 apple 2 liquid 2 1
3 pear 3 1
4 beef 5 2
5 water
然后您可以选择项目的所有属性:
SELECT p.name
FROM properties p
INNER JOIN item_properties ip ON p.id = ip.property_id
INNER JOIN items i on ip.item_id = i.id
WHERE i.name = 'banana'
或具有特定属性的所有项目:
SELECT i.name
FROM items i
INNER JOIN item_properties ip ON i.id = ip.item_id
INNER JOIN properties p ON ip.property_id = p.id
WHERE p.name = 'fruit'
我理解您是否不想在此时更改现有应用程序。但对于将来遇到这种情况的人来说,我真的建议一个更像这样的结构。
答案 1 :(得分:0)
使用CONCAT_WS()
连接值为yes
的所有列名称。 NULL
并未包含CONCAT_WS()
,因此返回no
列会将其排除在结果之外。
SELECT CONCAT_WS(',', IF(Banana = 'yes', 'Banana', NULL),
IF(Apple = 'yes', 'Apple', NULL),
IF(Pear = 'yes', 'Pear', NULL),
...) AS fruits
FROM yourTable
WHERE property = 'fruit';
答案 2 :(得分:0)
我建议您尝试更改要求以返回'banana,apple,pear'。如果你能做到这一点,那么你可以用以下模式将if语句硬编码到你的查询中:
select concat(
if (`banana`='yes', 'banana,', ''),
if (`apple` ='yes', 'apple,', ''),
if (`pear` ='yes', 'pear,', ''),
if (`beef` ='yes', 'beef,', ''),
if (`water` ='yes', 'water,', '')
) as properties
from table1
where ...