MySQL查询检查行的单元格中的值并返回列名

时间:2017-03-28 21:46:58

标签: php mysql

我整天都在努力解决某个问题,我决定寻求帮助。

我需要一个查询来检查整个表格行及其所有表格单元格的值是“是”'然后它需要给我这些列的名称。

example table

通过一个例子澄清: 在上表中,我需要检查所有单元格的水果行,其值为“是”'并将相应的列名返回给我。在这种情况下,结果将是' banana' apple' apple'和'梨'。

我希望这个例子有所帮助。

-- pseudo code
SELECT `COLUMN_NAMES`
FROM `My_Table`
ROW `fruit`
WHERE `value` = 'yes';

我还要注意,我无法重新安排数据库。数据库结构无法更改,因为我们已经在进行SELECT' property'之类的查询。在哪里'香蕉' ='是'(这将返回'水果')。我也需要它以相反的方式工作。

3 个答案:

答案 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 ...