Sql 如果特定列具有值,请选择多行

Sql 如果特定列具有值,请选择多行,sql,firebird,fastreport,Sql,Firebird,Fastreport,我有一张这样的桌子(简化): 表名:产品 productId, property, value ---------------------------- 1, color, red 1, shape, square 1, price, 1.00 ... 2, color, green 2, shape, triangle 2, price, 0.50 ... 10, color, red 10, shape, circle 10, price, 3.00 ... 我简化了它,但我希望它有意义。

我有一张这样的桌子(简化):

表名:产品

productId, property, value
----------------------------
1, color, red
1, shape, square
1, price, 1.00
...
2, color, green
2, shape, triangle
2, price, 0.50
...
10, color, red
10, shape, circle
10, price, 3.00
...
我简化了它,但我希望它有意义。对于一个特定的数据集,我有多行,在本例中是product。每行描述产品的不同属性

现在我想选择所有具有特定属性的产品,比如说
颜色
红色的所有产品。但不仅仅是颜色为红色的那一行,而是
颜色
红色
的每一个产品的每一行

对不起,这描述得很糟糕,但我希望你明白我的意思。考虑到上面的表结构,如果我想选择所有红色产品,我想以如下方式结束:

productId, color, shape, price
-------------------------------
1, red, square, 1.00
10, red, circle, 3.00
这有意义吗?也许有人能帮忙


顺便说一下:我不能更改给定的表结构。它来自外部应用程序。

一种方法使用
存在

select p.*
from products p
where exists (select 1
              from products p2
              where p2.productId = p.productId and
                    p2.property = 'color' and p2.value = 'red
             );
如果您希望这一行全部显示,则可以使用条件聚合来汇总:

select p.productid,
       max(case when p.property = 'color' then p.value end) as color,
       max(case when p.property = 'shape' then p.value end) as shape,
       max(case when p.property = 'price' then p.value end) as price
from products p
group by productId
having max(case when p.property = 'color' then p.value end) = 'red';

一种方法使用
存在

select p.*
from products p
where exists (select 1
              from products p2
              where p2.productId = p.productId and
                    p2.property = 'color' and p2.value = 'red
             );
如果您希望这一行全部显示,则可以使用条件聚合来汇总:

select p.productid,
       max(case when p.property = 'color' then p.value end) as color,
       max(case when p.property = 'shape' then p.value end) as shape,
       max(case when p.property = 'price' then p.value end) as price
from products p
group by productId
having max(case when p.property = 'color' then p.value end) = 'red';

请看一下pivot命令。如果列是静态的,这是我发现的将行转换为列的最佳方法。如果没有,可以通过动态sql实现,但要复杂一点。我使用该方法为产品属性构建视图,这听起来与您在这里所做的非常相似。

看看pivot命令。如果列是静态的,这是我发现的将行转换为列的最佳方法。如果没有,可以通过动态sql实现,但要复杂一点。我使用该方法为产品属性构建视图,这听起来与您在这里所做的非常相似。

属性列表是否已修复?属性列表是否已修复?Firebird没有pivot命令。很抱歉,我错过了Firebird标记。除非有任何对象,否则我不会删除这个问题,以防将来的用户发现它有用。我要说的是,在使用pivot之前,@GordonLinoff已经发布了我以前使用的解决方案+1.@MatthewBaker第二个建议确实很有效。Firebird没有pivot命令。很抱歉,我错过了Firebird标签。除非有任何对象,否则我不会删除这个问题,以防将来的用户发现它有用。我要说的是,在使用pivot之前,@GordonLinoff已经发布了我以前使用的解决方案+马修贝克第二个建议确实很有魅力,就是这样。工作起来很有魅力(第二个)。谢谢就这样。工作起来很有魅力(第二个)。谢谢