Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL query to update column in mysql based on a table?

Tags:

mysql

Assume I have the following tables:

tableA

a_name | age | country
Jordan |  5  | Germany
Jordan |  6  | Spain
Molly  |  6  | Spain
Paris  |  7  | France
John   |  7  | Saudi Arabia
John   |  5  | Saudi Arabia
John   |  6  | Spain

tableB

id (auto increment primary key) 
  | age | country      | group_num (initially null)
1 |  5  | Germany      |
2 |  6  | Spain        |
3 |  7  | France       |
4 |  7  | Spain        |
5 |  8  | France       |
6 |  9  | France       |
7 |  2  | Mexico       |
8 |  7  | Saudi Arabia |
9 |  5  | Saudi Arabia |

I want to be able to do some kind of select/update where I am able to get the following values for the "group_num" column:

tableB

id (auto increment primary key) 
  | age | country      | group_num
1 |  5  | Germany      | 1
2 |  6  | Spain        | 1
3 |  7  | France       | 1
4 |  7  | Spain        |
5 |  7  | France       | 2
6 |  9  | France       | 
7 |  2  | Mexico       |
8 |  7  | Saudi Arabia | 1
9 |  5  | Saudi Arabia | 1

group_num is assigned based on the criteria of:

1) Places person "a_name" went. 
2) Whether other people visited that same country. (regardless of age). 

The reason why id's 1,2,3,8,9 all have the same groupId is because Jordan, Molly, and Paris all happen to be somehow linked because of the above two criteria. (they all went to spain) and other countries, i.e. Germany was visited by Jordan who also visited spain, so it has the same group_num. Saudi Arabia was visited by John, who also visited spain, so it has the same group_num.

is there some SQL query or queries (may or may not involve creation of other "complementary" tables to get to the desired result shown above? (i.e. it is okay if group_num should first to be filled with auto_incrementing values like the "id", then updated later if it is necessary. (it is okay to have non-null values for the other value fields currently shown as "(empty)"

Cursors/iteration is very slow... The following are the steps I would perform to fill out those values, very slow process using cursors, if I can get rid of this it would be great:

  1. For tableA, we see that Jordan visited Germany at age 5. (Group_Num in tableB for [5,Germany] updated to 1).
  2. Jordan visits Spain at age 6. (Group Num for [6,Spain] updated to 1 to show its the same grouping as the same guy Jordan visited Spain)
  3. Molly visits Spain at age 6 (group_num for [6,Spain] updated to 1 since even though its a different person, the same age/country pair was hit)
  4. Paris visited France at age 7 (group_num in tableB updated to 2 since she is a different person, visited a completely different country, regardless of age.
  5. John visits Saudi Arabia at age 7 (group_num for [7,Saudi Arabia] in tableB updated to 3 for age+country pair)
  6. John visits Saudi Arabia at Age 5 (group_num for [5,Saudi Arabia] in tableB updated to 3 for age+country pair since its still John)
  7. John visits Spain at age 6 (group_num for [6,Spain] is already 1.. Jordan visited there before, there may be some grouping... so group_num for all the places John visited [6, Spain], [5, Saudi Arabia], and [7,Saudi Arabia] are all updated to 1
like image 871
Rolando Avatar asked Feb 08 '13 02:02

Rolando


1 Answers

You will need an iterative approach which will be based on each new item added to Table1, if you execute the following statements for each such item it will be fast and efficient:

Here is SQLFiddle for state of the db just before inserting the last record in Table 1.

BTW: Your example is not entirely consistent with your description , i assume you signed France 7 as group 1 by mistake, since Paris has no relation to no one in group 1.

Notice the selects that i'm executing:

  1. The first one searched for the group num of my previous places i have visited (this is my disjoint group , e.g. group num 3).
  2. The second is searches if there is a disjoint group that the inserted record may be related to, by searching group num for spain and age 6.

After finding out that you have two disjoint sets that becomes joined as a result of newly inserted record , you may that UPDATE all the group num previously assigned as the second group number to the first one, in such way:

UPDATE Table2 set group_num = 1 where group_num = 3

So i have not used any cursors , but this update is per insert for Table 1.

like image 107
Michael Avatar answered Oct 23 '22 23:10

Michael