SQL:仅返回具有不同数据的列

时间:2011-02-11 17:11:29

标签: sql oracle oracle11g

我有两行来自一个有很多列的表。如何只返回row1的值不等于row2的值的那些列?

我正在使用Oracle 11.1.0.07

~~编辑:澄清~~

实施例: 所以我有一个包含行的表:

1 a b c d e f g h i j k l
2 a x c d e x g h y j k l
3 a b x d e x g h x y k z

我想返回id(第一列)为1或3的行,只返回不同的列。所以:

1 c f i j l
3 x x x y z

列名。

实际上,我从中拉出的表有223007行和40列。以上是一个简化的例子。我想要比较两行(主键值各一行)。

4 个答案:

答案 0 :(得分:2)

如果您尝试转置转换您的row1和row2放入列中,那么这些问题可能会对您有所帮助:

旋转后,您只能选择那些具有row1_pivoted <> row2_pivoted

的元组

答案 1 :(得分:2)

首先,SQL语言不是为动态列生成而设计的。为此,您需要编写动态SQL,这应该在中间层或报告组件中完成。

其次,如果您要搜索的是比较两个特定行,那么最简单的解决方案可能是返回这些行并在中间层组件中进行分析。但是,如果您接受我们必须返回所有列并且您坚持在SQL中执行此操作,则这是一个解决方案:

With Inputs As
    (
    Select 1 As Col1,'a' As Col2,'b' As Col3,'c' As Col4,'d' As Col5,'e' As Col6,'f' As Col7,'g' As Col8,'h' As Col9,'i' As Col10,'j' As Col11,'k' As Col12,'l' As Col13
    Union All Select 2,'a','x','c','d','e','x','g','h','y','j','k','l'
    Union All Select 3,'a','b','x','d','e','x','g','h','x','y','k','z'
    )
    , TransposedInputs As
    (
    Select Col1, 2 As ColNum, Col2 As Value From Inputs
    Union All Select Col1, 3, Col3 From Inputs
    Union All Select Col1, 4, Col4 From Inputs
    Union All Select Col1, 5, Col5 From Inputs
    Union All Select Col1, 6, Col6 From Inputs
    Union All Select Col1, 7, Col7 From Inputs
    Union All Select Col1, 8, Col8 From Inputs
    Union All Select Col1, 9, Col9 From Inputs
    Union All Select Col1, 10, Col10 From Inputs
    Union All Select Col1, 11, Col11 From Inputs
    Union All Select Col1, 12, Col12 From Inputs
    Union All Select Col1, 13, Col13 From Inputs
    )
    , UniqueValues As
    (
    Select Min(Col1) As Col1, ColNum, Value
    From TransposedInputs
    Where Col1 In(1,3)
    Group By ColNum, Value
    Having Count(*) = 1
    )
Select Col1
    , Min( Case When ColNum = 2 Then Value End ) As Col2
    , Min( Case When ColNum = 3 Then Value End ) As Col3
    , Min( Case When ColNum = 4 Then Value End ) As Col4
    , Min( Case When ColNum = 5 Then Value End ) As Col5
    , Min( Case When ColNum = 6 Then Value End ) As Col6
    , Min( Case When ColNum = 7 Then Value End ) As Col7
    , Min( Case When ColNum = 8 Then Value End ) As Col8
    , Min( Case When ColNum = 9 Then Value End ) As Col9
    , Min( Case When ColNum = 10 Then Value End ) As Col10
    , Min( Case When ColNum = 11 Then Value End ) As Col11
    , Min( Case When ColNum = 12 Then Value End ) As Col12
    , Min( Case When ColNum = 13 Then Value End ) As Col13
From UniqueValues
Group By Col1

结果:

Col1 | Col2      | Col3      | Col4  | Col5      | Col6      | Col7  | Col8      | Col9      | Col10 | Col11 | Col12     | Col13
1   |   NULL    |   NULL    |   c   |   NULL    |   NULL    |   f   |   NULL    |   NULL    |   i   |   j   |   NULL    |   l
3   |   NULL    |   NULL    |   x   |   NULL    |   NULL    |   x   |   NULL    |   NULL    |   x   |   y   |   NULL    |   z

答案 2 :(得分:0)

嗯。当我重新阅读这个问题时,第一次尝试答案是错误的。所以...为了澄清,你有一些行/值

  1. a b c
  2. d e f
  3. a b c
  4. 并且您只想返回'd e f'行,因为它在其他位置没有重复的行?

答案 3 :(得分:0)

结果集中的列数不能是动态的(不使用动态SQL)。

您可能对Unpivot运算符感兴趣。这样可以将列作为行返回。 我自己还没有体验过它,所以不幸的是我无法帮助你:/

修改

我想手动转动镜头:)

select *
  from inputs;

 ID C1 C2 C3 C4 C5 C6
--- -- -- -- -- -- --
  1  a  b  c  d  e  f
  2  a  x  c  d  e  x
  3  a  b  x  d  e  x 

with unpivoted as(
  select id, 'c1'  as cn, c1  as cv from inputs union all
  select id, 'c2'  as cn, c2  as cv from inputs union all
  select id, 'c3'  as cn, c3  as cv from inputs union all
  select id, 'c4'  as cn, c4  as cv from inputs union all
  select id, 'c5'  as cn, c5  as cv from inputs union all
  select id, 'c6'  as cn, c6  as cv from inputs
)
select cn
      ,max(case when id = 1 then cv end) as id1
      ,max(case when id = 3 then cv end) as id3
  from unpivoted
 where id in(1,3)
 group 
    by cn
 having count(distinct cv) = 2;


CN ID1 ID3
-- --- ---
c3   c   x
c6   f   x

以上工作通过为每列和ID创建一行(2 * 6 = 12行) 然后我按列名称分组(指定为文字)。 我总会得到6组(每列一组)。在每组中,我将有两行(每个选定的ID一个) 在having子句中,我计算列的唯一值的数量。如果行具有相同的值,则唯一值的数量= 1.否则我们会出现不匹配。

注意1. id in(x,y)被推入视图中,因此我们选择整个表格。
注2.这不能扩展到比较2行以上 注3.这不涉及任何一列中的NULLS