我之前的问题非常令人困惑。对于我的疏忽,我很抱歉。在这里,我再次发布了我的问题以及更多信息。
我的表A和表B具有相同的列名(名称,ID,年龄,日期,类,......)但行数不同。表B是表A的重复表,并且具有较少的行。我想知道的是,如果记录具有相同的主键(id)并且任何其他列字段(名称,年龄,日期,类,...)不同,我将如何检索记录。但是,有一个条件。虽然记录具有相同的主键,但是如果仅更改日期,则不应检索记录。只有当两个表具有相同的主键,日期不同且任何列字段发生更改时,才应检索记录。
由于大约有200k条记录,大约有100列,我想使用高级SQL,因为如果我使用Select.. from... where
,我的SQL会太长,但我不知道哪条SQL使用
TableA
:
name age id date
------ --- -- ----------
David 11 1 11/01/2014
Claire 16 2 13/03/2014
Max 15 3 20/02/2014
John 14 4 19/09/2014
James 12 5 16/06/2014
TableB
:
name age id date
----- --- -- ----------
Max 15 3 15/05/2014
Will 14 4 12/04/2014
Bill 12 7 11/04/2014
Paul 11 8 24/12/2013
Kevin 13 9 03/04/2014
预期输出:
TableA TableB
name age id date name age id date
---- --- -- ---------- ---- --- -- ----------
John 14 4 19/09/2014 Will 14 4 12/04/2014
谢谢!
答案 0 :(得分:0)
您可以使用strcmp()函数来比较字符串。 http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#function_strcmp
例如,您想比较两个表中的名称和年龄,那么您的查询应如下所示:
select * from (select A.*,B.*,strcmp(concat(A.name,',',A.age),concat(B.name,',',B.age)) as diff from TableA A inner join TableB B on A.id = B.id)tablealias where tablealias.diff!=0
包括strcmp函数中的字段,如果它们发生更改,则会打扰
答案 1 :(得分:0)
最简单的方法是创建一个或多或少自动化的完整查询(制作一个使用EXPLAIN TABLE的小脚本,遍历列,忽略日期并进行选择)。每次更改表后,您都会重新运行该脚本。
更快的方法是引入一个在每次写入时更新的哈希列:触发器AFTER UPDATE和触发器AFTER INSERT计算所有重要列的哈希值(这也需要写下所有列,AFAIK),并将hashvalue写入hashfield。然后select只比较hashvalue。
如果您需要重复检查或UNIQUE KEY,该方法也很有用。在MySQL中,UNIQUE KEYs非常受限制,我认为16或32列是限制。
答案 2 :(得分:0)
由于您要检查编写where子句的所有列,因此可能会很繁琐,因此您可以使用information_schema.columns
获取该表的列名,然后使用动态查询来检查列差异。
以下可能是解决您问题的方法。
--Simulate your table structure
CREATE TABLE TableA
(
NAME VARCHAR(100),
AGE INT,
ID INT,
DATE_COL DATETIME
)
CREATE TABLE TableB
(
NAME VARCHAR(100),
AGE INT,
ID INT,
DATE_COL DATETIME
)
--Data for testing
INSERT INTO TABLEA(NAME, AGE, ID, DATE_COL) VALUES('David',11,1,'01/11/2014')
INSERT INTO TABLEA(NAME, AGE, ID, DATE_COL) VALUES('Claire',16,2,'03/13/2014')
INSERT INTO TABLEA(NAME, AGE, ID, DATE_COL) VALUES('Max',15,3,'02/20/2014')
INSERT INTO TABLEA(NAME, AGE, ID, DATE_COL) VALUES('John',14,4,'09/19/2014')
INSERT INTO TABLEA(NAME, AGE, ID, DATE_COL) VALUES('James',12,5,'06/16/2014')
INSERT INTO TABLEB(NAME, AGE, ID, DATE_COL) VALUES('Max',15,3,'05/15/2014')
INSERT INTO TABLEB(NAME, AGE, ID, DATE_COL) VALUES('Will',14,4,'04/12/2014')
INSERT INTO TABLEB(NAME, AGE, ID, DATE_COL) VALUES('Bill',12,7,'04/11/2014')
INSERT INTO TABLEB(NAME, AGE, ID, DATE_COL) VALUES('Paul',11,8,'12/24/2013')
INSERT INTO TABLEB(NAME, AGE, ID, DATE_COL) VALUES('Kevin',13,9,'04/03/2014')
--Solution Starts from here
CREATE TABLE #TableCols
(
ID INT IDENTITY(1,1),
COLUMN_NAME VARCHAR(1000)
)
--since both tables have same columns you can take columns of any 1 table
INSERT INTO #TableCols
(COLUMN_NAME)
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE table_name = 'TableA';
DECLARE @STARTCOUNT INT, @MAXCOUNT INT, @COL_NAME VARCHAR(1000), @QUERY VARCHAR(8000), @SUBQUERY VARCHAR(8000)
SELECT @STARTCOUNT = 1, @MAXCOUNT = MAX(ID) FROM #TableCols;
SELECT @QUERY = '', @SUBQUERY = ''
WHILE(@STARTCOUNT <= @MAXCOUNT)
BEGIN
SELECT @COL_NAME = COLUMN_NAME FROM #TableCols WHERE ID = @STARTCOUNT;
IF(@COL_NAME != 'DATE_COL' AND @COL_NAME != 'ID')
BEGIN
SET @SUBQUERY = @SUBQUERY + ' A.' + @COL_NAME + ' != B.' + @COL_NAME + ' OR ';
END
SET @STARTCOUNT = @STARTCOUNT + 1
END
SET @SUBQUERY = LEFT(@SUBQUERY, LEN(@SUBQUERY) - 3);
SET @QUERY = 'SELECT A.*, B.* FROM TableA A INNER JOIN TableB B ON A.ID = B.ID WHERE A.DATE_COL != B.DATE_COL AND (' + @SUBQUERY + ')';
EXEC (@QUERY);
希望这有帮助。