SQL查询:识别重复的值,并在未重复的列中显示值

时间:2018-07-27 16:10:39

标签: sql hadoop

我正在分析的Hadoop中有数据。有一些重复的条目,其中A,B列是重复的,而C列是不同的。我要做的是仅识别A,B重复项,然后为每个重复项打印出列C的不同值。

样本数据:

row,  data, input_date, INPUT__FILE__NAME
  0, data1,   20180702,         LOCATION1
  1, data1,   20180702,         LOCATION2
  2, data1,   20180702,         LOCATION2

  3, data2,   20180702,         LOCATION1
  4, data2,   20180702,         LOCATION1
  5, data2,   20180702,         LOCATION2
  6, data2,   20180702,         LOCATION3
  7, data2,   20180702,         LOCATION3

  8, data3,   20180702,         LOCATION2

  9, data4,   20180702,         LOCATION3

(请注意,INPUT__FILE__NAME是Hadoop数据所在的文件位置的元数据值。在这种情况下是相关的。但是就SQL查询而言,它可以像另一列一样对待,直到我知道)。

在此示例中,我将使用datainput_date来标识重复项。而且我希望能够看到它们各自的INPUT__FILE__NAME

所需的输出(如果有意义的话,可以更改输出的结构-我只需要不同的INPUT_FILE_NAME值):

    data, input_date, INPUT__FILE__NAME
   data1,   20180702,         LOCATION1
   data1,   20180702,         LOCATION2
   data2,   20180702,         LOCATION1
   data2,   20180702,         LOCATION2
   data2,   20180702,         LOCATION3

(因此,在输出中,我不需要看到data3data4,因为它们没有重复。)

我发现要确定重复项,我可以执行以下操作:

SELECT data, input_date, count(DISTINCT INPUT__FILE__NAME)
FROM table
GROUP BY data, input_date
HAVING count(DISTINCT INPUT__FILE__NAME)>1;

但是,我还没有找到一种方法来识别计数> 1的那些值,然后打印出这些不同的值(因为要识别> 1的值需要汇总,但是打印不同的值则需要取消-汇总)。可以在单个查询中完成吗?

2 个答案:

答案 0 :(得分:0)

您可以使用union all

select distinct t.data, t.input_date, t.INPUT__FILE__NAME
from table t
union all
select distinct t.data, t.input_date, t.INPUT__FILE__NAME
from table t
where not exists (select 1 
                  from table t1 
                  where t1.data = t.data and 
                        t1.input_date = t.input_date and
                        t1.INPUT__FILE__NAME <> t.INPUT__FILE__NAME
                 );

答案 1 :(得分:0)

我倾向于使用窗口功能:

select distinct data, input_date, input__file__name
from (select t.*,
             min(input__file__name) over (partition by data, input_date) as min_ifn,
             max(input__file__name) over (partition by data, input_date) as max_ifn
      from t
     ) t
where min_ifn <> max_ifn;