从只有前两列不同的表中选择数据

时间:2012-10-24 20:58:40

标签: sql sql-server tsql distinct

背景

我有一张有六列的表格。前三列创建了pk。我的任务是删除其中一个pk列。

我选择(使用不同)数据到临时表(不包括第三列),并尝试将所有数据插回到原始表中,第三列为每行“11”,因为这就是我被指示做。 (执行此操作后,DBA将删除此列)

但是,当我将这些数据插回到原始表中时,我得到了一个pk约束错误。 (令人震惊,我知道)

其他三列只是日期列,因此distinct select不会为每条记录创建唯一的pk。我想要实现的只是在前两列调用一个独特的,然后随意选择其他三列,因为我选择哪个日期并不重要(至少不在dev上)。

我尝试了什么

我发现以下帖子似乎达到了我的目的:

How do I (or can I) SELECT DISTINCT on multiple columns?

我尝试了Joel和Erwin的答案。

尝试1:

然而,在Joels的回答中,返回的集合太大了 - 内部联接并没有按照我的想法去做。选择不同的col1和col2有400列返回,但是当我使用他的解决方案时,返回600行。我检查了数据,实际上有重复的pk。这是我试图复制Joels的答案:

select a.emp_no, 
        a.eec_planning_unit_cde, 
        '11' as area, create_dte, 
        create_by_emp_no, modify_dte,
        modify_by_emp_no
from tempdb.guest.temp_part_time_evaluator b
inner join
(
    select emp_no, eec_planning_unit_cde
    from tempdb.guest.temp_part_time_evaluator
    group by emp_no, eec_planning_unit_cde
) a
ON b.emp_no = a.emp_no AND b.eec_planning_unit_cde = a.eec_planning_unit_cde

现在,如果我只执行内部select语句,则返回400行。如果我选择整个查询600行返回?内连接是不是只显示两组的交集?

尝试2:

我也尝试过Erwin的答案。这个有一个语法错误,我在go上搜索where子句的规范时遇到了麻烦(具体来说,他与(emp_no, eec_planning_unit_cde)一起使用的技巧)

以下是尝试:

select emp_no, 
    eec_planning_unit_cde, 
    '11' as area, create_dte, 
    create_by_emp_no, 
    modify_dte,
    modify_by_emp_no
where (emp_no, eec_planning_unit_cde) IN
(
    select emp_no, eec_planning_unit_cde
    from tempdb.guest.temp_part_time_evaluator
    group by emp_no, eec_planning_unit_cde
)

现在,我意识到我引用的帖子是postgresql。 T-SQL有没有类似的东西?试图谷歌括号不是很好。

问题概述:

  1. 为什么内连接不返回两组的交集?从谷歌搜索这是我认为应该做的
  2. 有没有其他方法可以实现我在t-sql尝试2中尝试的相同方法?
  3. 对我来说,无论我使用哪一个,或者我使用其他解决方案......我该怎么办呢?

3 个答案:

答案 0 :(得分:2)

select distinct将基于所有列,因此不保证前两个是不同的

select pk1, pk2, '11', max(c1), max(c2), max(c3) 
from table 
group by pk1, pk2 

答案 1 :(得分:1)

你可以尝试这个:

SELECT a.emp_no, 
        a.eec_planning_unit_cde, 
        b.'11' as area, 
        b.create_dte, 
        b.create_by_emp_no, 
        b.modify_dte,
        b.modify_by_emp_no
FROM 
(
    SELECT emp_no, eec_planning_unit_cde
    FROM tempdb.guest.temp_part_time_evaluator
    GROUP BY emp_no, eec_planning_unit_cde
) a 
JOIN tempdb.guest.temp_part_time_evaluator b 
     ON a.emp_no = b.emp_no AND a.eec_planning_unit_cde = b.eec_planning_unit_cde

这会让你对这些字段有所区别,但如果列之间的数据存在差异,你可能需要尝试更强力的approch。

SELECT a.emp_no, 
        a.eec_planning_unit_cde, 
        a.'11' as area, 
        a.create_dte, 
        a.create_by_emp_no, 
        a.modify_dte,
        a.modify_by_emp_no
FROM 
(
    SELECT ROW_NUMBER() OVER(ORDER BY emp_no, eec_planning_unit_cde) rownumber,
            a.emp_no, 
            a.eec_planning_unit_cde, 
            a.'11' as area, 
            a.create_dte, 
            a.create_by_emp_no, 
            a.modify_dte,
            a.modify_by_emp_no
    FROM tempdb.guest.temp_part_time_evaluator
) a
WHERE rownumber = 1

答案 2 :(得分:1)

我将逐一回复:

  1. 为什么内连接不返回两组的交集?从谷歌搜索这是我认为应该做的

    内部联接不做交集。不要理会这个表:

    T1   T2
    n s  n s
    1 A  2 X   
    2 B  2 Y
    2 C
    3 D
    

    如果按数字列连接两个表,则获取交集(2行)。你得到:

    select *
    from t1 inner join t2
       on t1.n = t2.n;
    
    | N | S |
    ---------
    | 2 | B |
    | 2 | B |
    | 2 | C |
    | 2 | C |
    

    并且,您的第二个查询方法:

    select *
    from t1 
    where t1.n in (select n from t2);
    
    | N | S |
    ---------
    | 2 | B |
    | 2 | C |
    
  2. 有没有其他方法可以实现我在t-sql尝试2中尝试的相同方法?

    是的,这个子查询:

    select *
    from t1 
    where not exists (
       select 1
       from t2
       where t2.n = t1.n
    );
    
  3. 对我来说,无论我使用哪一个,或者我使用其他解决方案......我该怎么办?

    是的,使用@JTC second query