从复杂的SQL表中获取数据

时间:2019-01-07 10:11:26

标签: sql oracle

我在下面提到了Oracle中的SQL表

FILE_NAME)            ROW_NUMBER     COL_NAME      COL_VALUE  
----------------------------------------- -------------------- -------------
EnivData.properties    1            Host                 server1.com          
EnivData.properties    1            Port                 8081                 
EnivData.properties    1            Username             server1user          
EnivData.properties    2            Host                 win-serv2.com        
EnivData.properties    2            Port                 9900                 
EnivData.properties    2            Username             server2-user-john    
EnivData.properties    3            Host                 linux-server3.com    
EnivData.properties    3            Port                 7898                 
EnivData.properties    3            Username             server3-user-mike    

下面提到的查询工作正常

select col_value 
from testmytable  
where col_name='Port' and 
      row_number = (select row_number 
                    from TESTMYTABLE  
                    where col_name='Host' and Col_Value='server1.com')

现在,我需要获取COL_VALUE的{​​{1}}的值,其中Username

我无法在SQL查询中的正确where子句中放置正确的结果(Host = server1.com and Port = 8081代表COL_VALUE)。

请帮助。

3 个答案:

答案 0 :(得分:2)

您可以使用以下查询来获取输出。但是,如果您确定每个行号总会有3个条目,那么可能会有比这更好的解决方案。

select * 
  from (
select col_name,col_value 
  from testmytable 
 where  row_number in (select row_number 
                         from TESTMYTABLE  
                        where col_name='Host' 
                         and Col_Value='server1.com')
   and row_number in (select row_number 
                         from TESTMYTABLE  
                        where col_name='Port' 
                         and Col_Value='8081')
        )x
   where x.col_name in('Host','Port','Username')

另一种解决方案是将行转换为列(即具有列host_val,port_val,username_val)并根据您希望搜索的值过滤列

例如:

with data
  as (
        select row_number
              ,max(case when col_name='Host' then col_value end) as host_val
              ,max(case when col_name='Port' then col_value end) as port_val
              ,max(case when col_name='Username' then col_value end) as username_val
          from testmytable 
         group by row_number
     )
select username_val
  from data  
where host_val='server1.com'  
  and port_val=8085

答案 1 :(得分:1)

键/值表最好通过聚合访问。这是查找主机'server1.com'和端口'8081'的用户名的方法。

select max(case when col_name = 'Username' then col_value end)
from testmytable  
group by row_number
having max(case when col_name = 'Host' then col_value end) = 'server1.com'
   and max(case when col_name = 'Port' then col_value end) = '8081';

答案 2 :(得分:1)

您可以JOIN将表本身与相关数据拉在一起:

SELECT
    t1.COL_VALUE AS 'Host',
    t2.COL_VALUE AS 'Port',
    t3.COL_VALUE AS 'User'
FROM       t AS t1
INNER JOIN t AS t2 ON t1.ROW_NUMBER = t2.ROW_NUMBER AND t2.COL_NAME = 'Port'
INNER JOIN t AS t3 ON t1.ROW_NUMBER = t3.ROW_NUMBER AND t3.COL_NAME = 'Username'
WHERE t1.COL_NAME = 'Host' -- this is important
-- you now have the three values available inside t1.COL_VALUE, t2.COL_VALUE
-- and t3.COL_VALUE waiting to be filtered
AND   t1.COL_VALUE = 'server1.com'
AND   t2.COL_VALUE = '8081'

您也可以使用EXISTS

SELECT col_value
FROM t
WHERE col_name = 'username'
AND EXISTS (
    SELECT 1
    FROM t
    WHERE row_number = t.ROW_NUMBER AND col_name = 'host' AND col_value = 'server1.com'
)
AND EXISTS (
    SELECT 1
    FROM t
    WHERE row_number = t.ROW_NUMBER AND col_name = 'port' AND col_value = '8081'
)
相关问题