关于sql:从仅前两列不同的表中选择数据

Select data from a table where only the first two columns are distinct

背景

我有一个包含六列的表。前三列创建pk。我的任务是删除pk列之一。

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

但是,当我将这些数据重新插入到原始表中时,出现了pk约束错误。 (震惊,我知道)

其他三列只是日期列,因此不同的选择并没有为每个记录创建唯一的pk。我想要实现的只是在前两列中调用一个distinct,然后随便选择其他三列,因为与选择哪个日期无关紧要(至少不在dev上使用)。

我尝试过的

我发现了以下帖子,似乎可以实现我想要的功能:

如何(或可以)在多列上选择DISTINCT?

我尝试了乔尔(Joel)和欧文(Erwin)的回答。

尝试1:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

现在,如果我仅执行内部选择语句,则将返回400行。如果我选择整个查询,则返回600行?内部联接不应该只显示两个集合的交集吗?

尝试2:

我也尝试了Erwin的回答。这是一个语法错误,我在查询where子句的规范时遇到了麻烦(特别是他与(emp_no, eec_planning_unit_cde)一起使用的技巧)

这是尝试:

1
2
3
4
5
6
7
8
9
10
11
12
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不会有类似的东西吗?尝试使用Google括号无法正常运行。

问题概述:

  • 为什么内部联接不返回两个集合的交集?从谷歌搜索这就是我认为应该做的
  • 还有另一种方法可以实现与我在t-sql尝试2中尝试的方法相同的方法吗?
  • 对我来说,使用哪一个都不重要,或者如果我使用其他解决方案,该如何解决呢?

  • 一个select unique将基于所有列,因此不能保证前两个是不相同的

    1
    2
    3
    SELECT pk1, pk2, '11', MAX(c1), MAX(c2), MAX(c3)
    FROM TABLE
    GROUP BY pk1, pk2


    我将一一答复:

  • 为什么内部联接不返回两个集合的交集?从谷歌搜索这就是我认为应该做的

    内部联接不做交集。让我们摆放这张桌子:

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

    如果按数字列连接两个表,则不会得到相交(2行)。您得到:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT *
    FROM t1 INNER JOIN t2
       ON t1.n = t2.n;

    | N | S |
    ---------
    | 2 | B |
    | 2 | B |
    | 2 | C |
    | 2 | C |

    然后,您的第二种查询方法:

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM t1
    WHERE t1.n IN (SELECT n FROM t2);

    | N | S |
    ---------
    | 2 | B |
    | 2 | C |
  • 是否有另一种方法可以实现与我在t-sql尝试2中尝试的方法相同的方法?

    是的,此子查询:

    1
    2
    3
    4
    5
    6
    7
    SELECT *
    FROM t1
    WHERE NOT EXISTS (
       SELECT 1
       FROM t2
       WHERE t2.n = t1.n
    );
  • 对我来说,使用哪一个都无关紧要,或者如果我使用其他解决方案...我应该如何解决呢?

    是的,使用@JTC第二个查询。


  • 您可以尝试以下操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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

    这将使您在这些字段上与众不同,但如果各列之间的数据存在差异,则可能必须尝试使用??更强力的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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