SQL查询:仅获取原始数据中的非重复列

SQL查询:仅获取原始数据中的非重复列,sql,teradata,Sql,Teradata,我尝试对如下表进行查询: 我需要有行中唯一不重复的列,在下面的示例中,我只需要:第一行15,第二行45,如果我有多个唯一变量,我需要它们都像1,1,2,2,3,4,5,我想要3,4,5 你们中有谁知道我如何在sql中做到这一点? 提前感谢。标准SQL Select指定要检索的列,因此我不知道如何使用标准Select直接提取数据 那我们怎么做呢 我认为“SQL”的方法是创建一个表,它可以是一个临时表,并将我们想要返回的值插入其中 在您的示例中,我怀疑现实生活要比我们创建一个包含两列“ID”和“Un

我尝试对如下表进行查询:

我需要有行中唯一不重复的列,在下面的示例中,我只需要:第一行15,第二行45,如果我有多个唯一变量,我需要它们都像1,1,2,2,3,4,5,我想要3,4,5

你们中有谁知道我如何在sql中做到这一点?
提前感谢。

标准SQL Select指定要检索的列,因此我不知道如何使用标准Select直接提取数据

那我们怎么做呢

我认为“SQL”的方法是创建一个表,它可以是一个临时表,并将我们想要返回的值插入其中

在您的示例中,我怀疑现实生活要比我们创建一个包含两列“ID”和“UniqueOp”的表复杂得多;由于任何一行中可能有多个唯一运算符,因此您不希望将其中任何一个作为主键,但我们可以将这两个主键都设置为Op重复,就好像Op不会是唯一的一样

然后用选择填充表格

删除表tblResults(如果存在); 创建表tblResultsID Int11 NOT NULL,UniqueOp Int11 NOT NULL PRIMARY KEYID,UniqueOp; 在tblResultsID中插入唯一选择ID,从tblBase中选择Op_1,其中Op_1Op_2和Op_1Op_3和Op_1Op_4和Op_1Op_5; 在tblResultsID中插入唯一选择ID,从tblBase中选择Op_2,其中Op_2Op_1和Op_2Op_3,Op_2Op_4和Op_2Op_5; 插入tblResultsID,唯一选择ID,从tblBase中选择Op_3,其中Op_3Op_1和Op_3Op_2和Op_3Op_4和Op_3Op_5; 插入tblResultsID,唯一选择ID,从tblBase中选择Op_4,其中Op_4Op_1和Op_4Op_2和Op_4Op_3和Op_4Op_5; 插入tblResultsID,唯一选择ID,从tblBase中选择Op_5,其中Op_5Op_1和Op_5Op_2和Op_5Op_3和Op_5Op_4; 从tblResults中选择ID、UniqueOp;
取消打印数据并聚合:

select id, op
from ((select id, op_1 as op, 1 as ind from t) union all
      (select id, op_2 as op, 2 as ind from t) union all
      (select id, op_3 as op, 3 as ind from t) union all
      (select id, op_4 as op, 4 as ind from t) union all
      (select id, op_5 as op, 5 as ind from t) 
     ) t
group by id, op
having count(*) = 1;
你也可以用一个大箱子来做这件事。假设没有空值:


根据您的要求,您可以使用以下任何选项-

SELECT ID,
CASE WHEN op_1 NOT IN (op_2,op_3,op_4,op_5) THEN op_1 ELSE NULL END op_1,
CASE WHEN op_2 NOT IN (op_1,op_3,op_4,op_5) THEN op_2 ELSE NULL END op_2,
CASE WHEN op_3 NOT IN (op_1,op_2,op_4,op_5) THEN op_3 ELSE NULL END op_3,
CASE WHEN op_4 NOT IN (op_1,op_2,op_3,op_5) THEN op_4 ELSE NULL END op_4,
CASE WHEN op_5 NOT IN (op_1,op_2,op_3,op_4) THEN op_5 ELSE NULL END op_5
FROM your_table 
输出为-

ID      op_1    op_2    op_3    op_4    op_5
12345                                   15
12346                   45      
ID      VALUE
12346   45
12345   15
或选择2

SELECT ID,op_1 AS VALUE
FROM your_table WHERE op_1 NOT IN (op_2,op_3,op_4,op_5)

UNION ALL

SELECT ID,op_2 AS VALUE
FROM your_table WHERE op_2 NOT IN (op_1,op_3,op_4,op_5)

UNION ALL

SELECT ID,op_3 AS VALUE
FROM your_table WHERE op_3 NOT IN (op_1,op_2,op_4,op_5)

UNION ALL

SELECT ID,op_4 AS VALUE
FROM your_table WHERE op_4 NOT IN (op_1,op_2,op_3,op_5)

UNION ALL

SELECT ID,op_5 AS VALUE
FROM your_table WHERE op_5 NOT IN (op_1,op_2,op_3,op_4)
输出为-

ID      op_1    op_2    op_3    op_4    op_5
12345                                   15
12346                   45      
ID      VALUE
12346   45
12345   15

下面是一个特定于Teradata的答案,使用

虽然unpivot使用起来有点混乱,但它没有一堆case语句或联合那么冗长。如果你只是跑

select
*
from
<your table>
UNPIVOT ((op_val) for (op_type) in (op_1,op_2,op_3,op_4,op_5)) t
更清楚一点。5个op*列变为op_类型,op*列中的值变为op_val。

这将处理空值:

当列表包含null值时,不能使用not in,但可以通过case when null else end有效地反转逻辑

下面是一个针对SQL Server运行的示例。注意,它不处理后面的逗号。

表中只有那5列?如果出现重复,您希望列中的值是多少。。。NULL?您可以规范化架构。那么这将是一个非常简单的查询,GROUP BY和COUNT*=1。如果一行中有多个唯一值:`1,1,2,3,4',该怎么办?这个表的设计非常糟糕。请像Paul said.MySQL或Teradata那样对其进行规范化?当数据以行变成列的方式进行非规范化时,这是唯一的选择。当然,查询不会随着列数的增加而扩展;这就是为什么所有sql人员都如此痴迷于规范化。
select
    id,
    trim(trailing ',' from concat(
        case when op1 in (op2, op3, op4, op5)
             then null else cast(op1 as varchar) + ',' end,
        case when op2 in (op1, op3, op4, op5)
             then null else cast(op2 as varchar) + ',' end,
        case when op3 in (op1, op2, op4, op5)
             then null else cast(op3 as varchar) + ',' end,
        case when op4 in (op1, op2, op3, op5)
             then null else cast(op4 as varchar) + ',' end,
        case when op5 in (op1, op2, op3, op4)
             then null else cast(op5 as varchar) + ',' end
        )
    )
from t;