0

我的表的一部分如下,

Key|Value
---------
 A | V1
 B | V2
 C | V3

我知道以下查询肯定不会返回任何结果,但是获得肯定结果的正确查询是什么,即“1”。

我的意思是我应该应用什么查询来检查 A 的值为 V1,B 的值为 V2,然后返回“1”。如果 A 或 B 有不同的结果,则新查询应该无法返回任何内容。

假设该表是一个键/值对的映射。这里唯一的区别是它不是 Java 映射,而是 Oracle Db 中的表。那么,如何获得同时满足键/值对的结果。

select 1 from myTable 
where (key = 'A' and value = 'V1') 
  AND (key = 'B' and value = 'V2');

让我知道桌子本身的设计是否需要一些改变。

4

3 回答 3

2

我想这就是你想要的。

select 1 from dual
 where exists(
              select 1
                from mytable
               where key = 'A' and value = 'V1')
   and exists(
              select 1
                from mytable
               where key = 'B' and value = 'V2')
于 2013-08-14T10:03:59.403 回答
1

使用我的心理调试能力:

如果出现以下情况,您希望值为 1:

  1. 有一行 Key="A" 和 value="V1" AND
  2. 还有另一行 Key="B" 和 value="V2"

要获得像第一个这样的行,您需要:

select 1 from myTable where key = 'A' and value = 'V1'

要获得像第二个一样的行,您需要

select 1 from myTable where key = 'B' and value = 'V2'

现在您需要确保这两行都存在。

这听起来并不简单,因为 SQL 检查where单行上的所有条件,所以语句如下:

select 1 from myTable where key = 'A' and key = 'B'

是荒谬的,因为它要求键列同时具有两个不同的值。

一种(低效)解决方案是将表连接到自身

select 1 
from mytable t1
  cross join mytable t2
where t1.Key = 'A' and t1.Value='V1'
  and t2.Key = 'B' and t2.Value='V2'

这将生成表格的笛卡尔积,将每一行与其他行连接起来。它会产生

t1.Key|t1.Value|t2.Key|t2.Value
-------------------------------
 A    | V1     |  A    |  V1
 B    | V2     |  A    |  V1
 C    | V3     |  A    |  V1
 A    | V1     |  B    |  V2   <-- the row you need
 B    | V2     |  B    |  V2   
 C    | V3     |  B    |  V2   
 A    | V1     |  C    |  V3   
 B    | V2     |  C    |  V3   
 C    | V3     |  C    |  V3   

并使您能够同时检查原始表的两行。

请注意,这将生成一个 count^2 行的表,因此如果表的行数超过几行,或者您需要同时检查两行以上,请不要使用它。

于 2013-08-14T10:02:50.680 回答
0

如果您只想检查是否有满足某些条件的行,您可以使用以下构造

select count(*) from dual
where exists (
               select 1  
               from myTable 
               where (key = 'A' and value = 'V1')                       
              )
 AND exists (
               select 1  
               from myTable 
               where (key = 'B' and value = 'V2')                       
              );
于 2013-08-14T09:50:38.817 回答