Вопрос

I have two tables as below:

logs

id | user   | log_id
---------------------
1  | user1  | abc 
2  | user2  | def 
3  | user1  | xyz 
...

users

id | user   | code
---------------
1  | user1  | 1234
2  | user2  | 9876
3  | user1  | 5678
...

I want to add log_id to users and update it with log_id's from Table1, to make Table2 as below:

id | user  | code   | log_id
---------------------------
1  | user1 | 1234   | abc
2  | user2 | 9876   | def
3  | user1 | 5678   | xyz    
...

The only way to match rows in logs and users is using the user field, and the chronological order they appear in the tables. id, as you may have guessed, is the primary key in both tables.

Much appreciated if someone could help me with the query for this. Thanks.

Это было полезно?

Решение 4

I figured out the solution. I added 2 columns rank and prev_user in both tables, and incremented the value for rank from 1 for the first record for user_x to n for the nth record for user_x, as below:

ALTER TABLE users ADD COLUMN rank tinyInt(1);
ALTER TABLE users ADD COLUMN prevuser varchar(50);
SET @prevuser = '';
SET @rank = 0;
UPDATE users 
SET rank = (@rank:=IF(@prevuser != user,1,@rank+1)),
    prevuser = (@prevuser := user)
ORDER BY user,id;
ALTER TABLE users DROP COLUMN prevuser;

and,

ALTER TABLE logs ADD COLUMN rank tinyInt(1);
ALTER TABLE logs ADD COLUMN prevuser varchar(50);
SET @prevuser = '';
SET @rank = 0;
UPDATE logs 
SET rank = (@rank:=IF(@prevuser != user,1,@rank+1)),
    prevuser = (@prevuser := user)
ORDER BY user,id;
ALTER TABLE logs DROP COLUMN prevuser;

Now records can be matched between the tables using user & rank. I added the field log_id to users and updated it as below:

UPDATE users, logs SET users.log_id=logs.log_id WHERE users.user=logs.user AND users.rank = logs.rank;

And voila!

Другие советы

If the id fields are always matched then the reply by Ronak Shah would be my choice.

If the ids do not match then possibly something like this:-

Firstly:-

ALTER TABLE table1 ADD COLUMN code VARCHAR(25);

Then an update like this:-

UPDATE table2
INNER JOIN
(
    SELECT id, user, code, @rank2:=IF(@prev_user2 = user, @rank2+1, 1) AS rank, @prev_user2 := user
    FROM table2
    CROSS JOIN (SELECT @rank2:=0, @prev_user2:='') sub2
    ORDER BY user, id
) tab_2
ON table2.id = tab_2.id
INNER JOIN
(
    SELECT id, user, log_id, @rank1:=IF(@prev_user1 = user, @rank1+1, 1) AS rank, @prev_user1 = user
    FROM table1
    CROSS JOIN (SELECT @rank1:=0, @prev_user1:='') sub1
    ORDER BY user, id
) tab_1
ON tab_1.user = tab_2.user
AND tab_1.rank = tab_2.rank
SET table2.log_id = tab_1.log_id;

What this is doing is a pair of sub queries which adds a rank to each tables records (I have added the rank within the user, which should make it cope a bit better if one user on one table has an extra record). The results of these sub queries are joined together, and then joined to table2 to do the actual update (the sub query for table2 to get the rank can be joined to table2 based on id).

This seems to work when done in SQL fiddle:-

http://www.sqlfiddle.com/#!2/ad8a6b/1

Try this:

UPDATE dbo.Table2 A
SET A.log_id = B.log_id
INNER JOIN dbo.Table1 B
ON A.user = B.user

But first you have to add log_id column to table2 with alter query.

try this:

alter table table1 add column code varchar(100);

update table1,table2 set table1.code = table2.code where table1.id=table2.id and table1.user=table2.user;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top