简体   繁体   English

比较表中的行以了解字段之间的差异

[英]Comparing rows in table for differences between fields

I have a table (client) with 20+ columns that is mostly historical data. 我有一个包含20多个列的表(客户端),大部分都是历史数据。

Something like: id|clientID|field1|field2|etc...|updateDate 像这样的东西:id | clientID | field1 | field2 | etc ... | updateDate

If my data looks like this: 如果我的数据如下所示:

10|12|A|A|...|2009-03-01
    11|12|A|B|...|2009-04-01
    19|12|C|B|...|2009-05-01
    21|14|X|Y|...|2009-06-11
    27|14|X|Z|...|2009-07-01

Is there an easy way to compare each row and highlight the differences in the fields? 有没有一种简单的方法可以比较每一行并突出显示字段之间的差异? I need to be able to simply highlight the fields that changed between revisions (except for the key and the date of course) 我需要能够简单地突出显示各修订版本之间更改的字段(密钥和课程日期除外)

There may be multiple fields updated in each new row (or just one). 每个新行中可能有多个更新的字段(或只有一个)。

This would be on a client by client basis so I could select on the clientID to filter. 这将在每个客户端的基础上进行,因此我可以选择clientID进行过滤。

It could be on the server or client side, which ever is easiest. 它可以在服务器或客户端,这是最简单的。

More details I should expand my description a little: I'm looking to just see if there was a difference between the fields (one is different in any way). 更多详细信息,我应该稍微扩展一下描述:我只是想看看这些字段之间是否存在差异(一个字段在任何方面都不同)。 Some of the data is numeric, some is text others are dates. 一些数据是数字,一些是文本,其他是日期。 A more complete example might be: 一个更完整的示例可能是:

10|12|A|A|F|G|H|I|J|...|2009-03-01
    11|12|A|B|F|G|H|I|J|...|2009-04-01
    19|12|C|B|F|G|Z|I|J|...|2009-05-01 ***
    21|14|X|Y|L|M|N|O|P|...|2009-06-11
    27|14|X|Z|L|M|N|O|P|...|2009-07-01

I'd want to be able to isplay each row for clientID 12 and highlight B from row 11 and C & Z from row 19. 我希望能够播放clientID 12的每一行,并突出显示第11行的B和第19行的C&Z。

Any expression in SQL must reference columns only in one row (barring subqueries). SQL中的任何表达式都只能引用一行中的列(禁止子查询)。

A JOIN can be used to make two different rows into one row of the result set. 可以使用JOIN将两个不同的行变成结果集的一行。

So you can compare values on different rows by doing a self-join. 因此,您可以通过自联接比较不同行上的值。 Here's an example that shows joining each row to every other row associated with the same client (excluding a join of a row to itself): 这是一个示例,该示例显示将每一行连接到与同一客户端相关联的每隔一行(不包括将一行连接到自身)。

SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)

Now you can write expressions that compare columns. 现在,您可以编写比较列的表达式。 For example, to restrict the above query to those where field1 differs: 例如,将上述查询限制为field1不同的查询:

SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;

You don't specify what kinds of comparisons you need to make, so I'll leave that to you. 您无需指定需要进行哪种比较,因此我将其留给您。 The key point is that in general, you can use a self-join to compare rows in a given table. 关键点是,通常,您可以使用自联接比较给定表中的行。


Re your comments and clarification: Okay, so your "difference" is not simply by value but by ordinal position of the row. 关于您的评论和说明:好的,因此,您的“差异”不仅是按值,而是按行的顺序位置。 Remember that relational databases don't have a concept of row number, they only have order of rows with respect to some order you must specify in an ORDER BY clause. 请记住,关系数据库没有行号的概念,它们仅具有相对于您必须在ORDER BY子句中指定的某些顺序的行顺序。 Don't confuse the " id " pseudokey with row number, the numbers are assigned as monotonically increasing only by coincidence of their implementation. 不要将“ id ”伪键与行号混淆,仅通过实现它们的巧合将数字分配为单调递增。

In MySQL, you could take advantage of user-defined variables to achieve the effect you're looking for. 在MySQL中,您可以利用用户定义的变量来实现所需的效果。 Order the query by clientId and then by id , and track values per column in MySQL user variables. clientId然后按id clientId查询,并跟踪MySQL用户变量中每列的值。 When the value in a current row differs from the value in the variable, do whatever highlighting you were going to do. 当当前行中的值与变量中的值不同时,请执行突出显示操作。 I'll show an example for one field: 我将显示一个字段的示例:

SET @clientid = -1, @field1 = '';
SELECT id, clientId, field1, @clientid, @field1,
  IF(@clientid <> clientid, 
    ((@clientid := clientid) AND (@field1 := field1)) = NULL,
    IF (@field1 <> field1, 
      (@field1 := field1), 
      NULL
    )
  ) AS field1_changed
FROM client c
ORDER BY clientId, id;

Note this solution is not really different from just selecting all rows with plain SQL, and tracking the values with application variables as you fetch rows. 请注意,此解决方案与仅使用普通SQL选择所有行并在获取行时使用应用程序变量跟踪值并没有什么不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM