在 Teradata SQL 中查找给定列的哪些行具有不同的值

Posted

技术标签:

【中文标题】在 Teradata SQL 中查找给定列的哪些行具有不同的值【英文标题】:Find which rows have different values for a given column in Teradata SQL 【发布时间】:2012-11-22 09:21:45 【问题描述】:

我正在尝试比较来自同一 ID 的两个地址以查看它们是否匹配。例如:

Id  Adress Code     Address
1   1               123 Main
1   2               123 Main
2   1               456 Wall
2   2               456 Wall
3   1               789 Right
3   2               100 Left

我只是想弄清楚每个 ID 的地址是否匹配。所以在这种情况下,我只想返回 ID 3,因为地址代码 1 和 2 的地址不同。

【问题讨论】:

酷!你试过什么? 哪个 RDBMS?如果是 SQL Server,请尝试查看 this question。 抱歉,我在 Teradata 中使用它。 您必须阅读有关联接的信息 我建议你仔细观察你的桌子。 RDBMS 背后的原则之一是唯一性的概念,它使您的生活变得更加轻松。这个想法是每一行代表一个不同的实体,不应重复任何行;唯一性会使这个问题不存在。如果还不算太晚,我建议您重新审视您的餐桌设计。 【参考方案1】:

将表与自身连接起来,并为其赋予两个不同的别名(以下示例中的AB)。这允许比较同一个表的不同行。

SELECT DISTINCT A.Id
FROM
    Address A
    INNER JOIN Address B
        ON A.Id = B.Id AND A.[Adress Code] < B.[Adress Code]
WHERE
    A.Address <> B.Address

“小于”比较&lt; 可确保您获得 2 个不同的地址,并且不会两次获得相同的 2 个地址代码。改用“不等于”&lt;&gt;,将产生代码为 (1, 2) 和 (2, 1); A 别名和B 别名依次对应。

join 子句负责配对 where 子句作为 where 子句测试附加条件的行。


上述查询适用于任何地址代码。如果你想将地址与特定地址代码进行比较,你可以将查询更改为

SELECT A.Id
FROM
    Address A
    INNER JOIN Address B
        ON A.Id = B.Id
WHERE                     
    A.[Adress Code] = 1 AND
    B.[Adress Code] = 2 AND
    A.Address <> B.Address

我想这可能有助于查找帐单地址(例如地址代码 = 1)与送货地址(地址代码 = 2)不同的客户。

【讨论】:

【参考方案2】:

这适用于 PL/SQL:

select count(*), id,address from table group by id,address having count(*)<2

【讨论】:

【参考方案3】:

您可以通过以下方式使用组来执行此操作:

select id, addressCode
from t
group by id, addressCode
having min(address) <> max(address)

另一种写法可能看起来更清晰,但效果不佳:

select id, addressCode
from t
group by id, addressCode
having count(distinct address) > 1

【讨论】:

【参考方案4】:

就个人而言,我会使用 Perl 或 Python 以格式将它们打印到文件中

<COL_NAME>:  <COL_VAL>

对于每一行,以便文件的行数与列数一样多。然后我会在两个文件之间做一个diff,假设你在Unix上或者在另一个操作系统上使用一些等效的工具来比较它们。如果您有多个记录集(即多于一行),我会在每个文件行之前添加,然后该文件将有 NUM_DB_ROWS * NUM_COLS 行

【讨论】:

-1。对不起。将 SQL 数据转储到外部文件以使用 Perl 或 Python 进行比较是错误的; “我知道如何使用这把锤子,所以让我们像钉子一样对待一切”。该解决方案根本没有解决所提出的问题,即如何在 SQL 中 编写脚本来执行此操作的优点是它可以用于任何表,而无需指定列名,因为它们可以从系统表中读取。我已经为 QA 编写了几个这样的脚本,他们必须比较不同数据库中的记录集,而只有 SQL 是不够的,即使这样做,他们也必须为每个不同的表编写自定义查询以反映不同的列。我的脚本中唯一特定于表的数据,当然,除了名称、模式和服务器等表详细信息之外,将是条件字符串。 但与必须拼出每个列名相比,这是相对较少的自定义配置。 SQL 是一个很棒的工具,但有一些严格的限制,可以在它之外更好地克服这些限制(例如脚本语言),而不是看起来像 Rube Goldberg 机器的 SQL 语句。我喜欢清洁、结构和简单。你可以保持你的反对意见,我不是要你改变这一点,这个阐述更多的是我对世界其他地方的哲学 没有。 SQL 用于处理数据,并且数据已经存在于数据库中。将其移出数据库以查找重复项绝对具有零优势(如其他答案所示)。同样,使用适当的工具来完成这项工作,而您的答案却没有。如果您在谈论表示存储过程的“脚本”,那很好。将数据物理导出到外部文件,然后以另一种语言运行外部脚本任务(您通过“读取系统表”创建),这是完全错误的。 (当我解释我的反对意见时,我只是有礼貌。) 你很清楚我的意思,但澄清一下,这样你就不会感到困惑:当然,我的意思是说 SQL 是为处理数据而设计的 你已经存储在数据库中. 或许,如果您想尝试在 Perl 或 Python 中做所有事情(您显然是“一刀切”的解决方案),您可能会意识到编程不仅仅是操作文本文件。 IOW,工具箱中的工具不仅仅是锤子。 “从数据库中取出非常好的数据,将其提取到单独的文本文件中,在那里处理数据,然后更新数据库”???真的???

以上是关于在 Teradata SQL 中查找给定列的哪些行具有不同的值的主要内容,如果未能解决你的问题,请参考以下文章

Teradata 中数据计算和导出

Teradata中“日期”数据类型列的最近30天

SQL Server 在特定列的所有行中查找和替换特定单词

Teradata SQL:最大(最大)、第二和第三大列名

如何在 Oracle SQL 中查找最具体的匹配行

MySQL 表列数和行大小有哪些限制?