如何在mysql中的两个表之间获取比较差异列值

时间:2018-11-20 19:19:30

标签: mysql database

status_tb

+----+----------+-------------+----------+
| id | status   | description | state_id |
+----+----------+-------------+----------+
|  1 |     new  | north       | 1        |
|  2 |   assign | south       | 2        |
|  3 |Postponed | east        | 2        |
|  4 |    Fixed | west        | 3        |
|  8 | Verified | north-east  | 1        |
|  9 |   Closed | south-west  | 2        |
| 35 |     Test | South-test  | 4        |
+----+----------+-------------+----------+

status_backup_tb

+----------+----+----------+-------------+----------+
|backup_id | id | status   | description | state_id |
+----------+----+----------+-------------+----------+
|  1       |  1 |new       | north       | 1        |
|  2       |  2 |assign    | south       | 2        |
|  3       |  3 |Postponed | east        | 2        |
|  4       |  4 | Fixed    | west        | 3        |
|  5       |  8 | Verified | north-east  | 1        |
|  6       |  9 | Closed   | south-west  | 2        |
|  7       |  35| Rejected | Testing     | 4        |
+----------+----+----------+-------------+----------+

想要的结果:仅列更改,旧值和新值

 |new_id | id |Column_changed| Old_value   |New_value |
 +-------+----+--------------+-------------+----------+
 |1      | 35 | status       | Test        | Rejected |
 |2      | 35 |description   | South-test  | Testing  |  
 +-------+----+--------------+-------------+----------+

如果state_idstatus是更改的那个,我想获取id, status and state_id列以及它们的old_values和new_values。

已经尝试使用它,但是没有用

SELECT MIN(TableName) as TableName, ID, COL1, COL2, COL3 ...
FROM
(
 SELECT 'Table A' as TableName, A.ID, A.COL1, A.COL2, A.COL3, ...
 FROM A
 UNION ALL
 SELECT 'Table B' as TableName, B.ID, B.COL1, B.COl2, B.COL3, ...
 FROM B
 ) tmp
GROUP BY ID, COL1, COL2, COL3 ...
HAVING COUNT(*) = 1
ORDER BY ID

2 个答案:

答案 0 :(得分:1)

一种方法是获取各个Select查询中各个字段的所有更改。最终Union这多个查询的结果。

我们在两个表之间使用JOIN id,并且条件是相应的列值不匹配。

(SELECT 
   s.id, 
   'status' AS Column_changed, 
   s.status AS Old_value, 
   b.status AS New_value 
 FROM status_tb AS s
 JOIN status_backup_tb AS b 
   ON b.id = s.id AND 
      b.status <> s.status)

UNION ALL 

(SELECT 
   s.id, 
   'description' AS Column_changed, 
   s.description AS Old_value, 
   b.description AS New_value 
 FROM status_tb AS s
 JOIN status_backup_tb AS b 
   ON b.id = s.id AND 
      b.description <> s.description)

UNION ALL

(SELECT 
   s.id, 
   'state_id' AS Column_changed, 
   s.state_id AS Old_value, 
   b.state_id AS New_value 
 FROM status_tb AS s
 JOIN status_backup_tb AS b 
   ON b.id = s.id AND 
      b.state_id <> s.state_id)

ORDER BY id

答案 1 :(得分:0)

尝试以下方法:

class range_t : public ranges::view_facade<range_t>
{
    friend ranges::range_access;

    struct cursor {
        cursor() = default;
        cursor(FlatMultiMap& self, std::size_t index)
            : self(&self)
            , index(index)
        {}

        // other implementation stuff
    private:
        // I want to get this data from outside cursor class
        FlatMultiMap* self;
        std::size_t   index;
    };

    cursor begin_cursor() const
    {
        return { *self, index };
    }
    cursor end_cursor() const
    {
        return { *self, end_index };
    }

    FlatMultiMap* self;
    std::size_t   index;
    std::size_t   end_index;

public:
    range_t() = default;
    range_t(FlatMultiMap& self, std::size_t index, std::size_t end_index)
        : self(&self)
        , index(index)
        , end_index(end_index)
    {}

    template<class I, class S>
    range_t(I iterator, S sentinel)
    {
         // how to do this?
         iterator.self  // Error
    }

};