Update unique column of multiple rows , skip the duplicates - duplicates

Here is my main table Contacts
ID | Name | Mobile
1 | Jai | 123
2 | Dave | 456
3 | Peter| 789
ID -> Primary Key Column
Mobile -> an unique column
I have a new update request. The data resides in another table (say table dummy).
ID | Name | Mobile
1 | Jai | 456
2 | Dave | 789
3 | Peter| 123
To update data from table dummy to Contacts, I can easily fire an update query by joining these two tables and update the Mobile of Contacts. But it is possible only if the data to be updated from Mobile column of dummy table is unique.
That is, if the dummy table content is like below,
ID | Name | Mobile | Status
1 | Jai | 789 |
2 | Dave | 456 |
3 | Peter| 456 |
In this case, I want to skip the rows 1 & 3 and update only the second row.
And I need to update the STATUS column (Skipped or Updated).
Is it possible by few queries?

Related

MySql add relationships without creating dupes

I created a table (t_subject) like this
| id | description | enabled |
|----|-------------|---------|
| 1 | a | 1 |
| 2 | b | 1 |
| 3 | c | 1 |
And another table (t_place) like this
| id | description | enabled |
|----|-------------|---------|
| 1 | d | 1 |
| 2 | e | 1 |
| 3 | f | 1 |
Right now data from t_subject is used for each of t_place records, to show HTML dropdowns, with all the results from t_subject.
So I simply do
SELECT * FROM t_subject WHERE enabled = 1
Now just for one of t_place records, one record from t_subject should be hidden.
I don't want to simply delete it with javascript, since I want to be able to customize all of the dropdowns if anything changes.
So the first thing I though was to add a place_id column to t_subject.
But this means I have to duplicate all of t_subject records, I would have 3 of each, except one that would have 2.
Is there any way to avoid this??
I thought adding an id_exclusion column to t_subject so I could duplicate records only whenever a record is excluded from another id from t_place.
How bad would that be?? This way I would have no duplicates, so far.
Hope all of this makes sense.
While you only need to exclude one course, I would still recommend setting up a full 'place-course' association. You essentially have a many-to-many relationship, despite not explicitly linking your tables.
I would recommend an additional 'bridging' or 'associative entity' table to represent which courses are offered at which places. This new table would have two columns - one foreign key for the ID of t_subject, and one for the ID of t_place.
For example (t_place_course):
| place_id | course_id |
|----------|-----------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 3 |
As you can see in my example above, place 3 doesn't offer course 2.
From here, you can simply query all of the courses available for a place by querying the place_id:
SELECT * from t_place_course WHERE place_id = 3
The above will return both courses 1 and 3.
You can optionally use a JOIN to get the other information about the course or place, such as the description:
SELECT `t_course`.`description`
FROM `t_course`
INNER JOIN `t_place_course`
ON `t_course`.`id` = `t_place_course`.`course_id`
INNER JOIN `t_place`
ON `t_place`.`id` = `place_id`

Two identical mysql tables, one is empty, how to populate it?

I have one table full of data (around 20,000 values)
table_1
ID | name | e-mail (only as an example, it could be just normal TEXT)
1 |alfaa | e-mail alfaa 1
2 |alfaa | e-mail alfaa 2
3 |beta | e-mail beta
4 |celta | e-mail celta
...
and other identical table with the "e-mail" column empty, and some names that are also contained in table_1, alltough with a different ID
table_2 (around 5,000 values)
ID | name | e-mail
1 |beta |
2 |alfaa |
3 |celta |
...
My question is, how can I populate the empty e-mail column of table_2 with values from e-mail column of table_1 WHERE table_2.name = table_1.name ?
The IDs are different AND table_1 contains some cases of several e-mails for the same name.
(well, I think I also could to manage it to work without several e-mails for the same name)
This is what I've got:
UPDATE table_2, table_1
SET table_2.email = table_1.email
WHERE table_1.name = table_2.name;
See this sqlfiddle
Let's talk about Database Normalization.
You have found a problem in the way your database schema is designed, mainly, you're store a lot of data in multiple places. This can easily lead to tables drifting out of sync from each other, wasted storage space, and costly lookups.
Let me show you what I'm talking about.
Case 1. Synchronizing tables.
Let's say you do populate your table_1, table_2 correctly. You get something like this:
table_1 table_2
ID_1 | name | email ID_2 | name | email
1 | bob | bob#cat.com 1 | adam | adam#dog.com
2 | adam | adam#dog.com 2 | bob | bob#cat.com
3 | bob | bob#dog.com 3 | bob | bob#dog.com
4 | joe | joe#dog.com
Note that I'm storing bob's two emails twice. This might not seem like much but if bob has 5 emails, and you add a table_3, then you're storing 15 records to only refer to 5 unique pieces of information.
Now let's say you're adam, and you want to update your email, let's say you want to change your email to adam#cat.com. And you do it in program 1, which uses table_1, but you don't do it in program 2, which uses table_2. What do you get when you hit the update?
table_1 table_2
ID_1 | name | email ID_2 | name | email
1 | bob | bob#cat.com 1 | adam | adam#dog.com
2 | adam | adam#cat.com 2 | bob | bob#cat.com
3 | bob | bob#dog.com 3 | bob | bob#dog.com
4 | joe | joe#dog.com
Adam now has a different email depending on whether he uses program 1 or program 2. So to solve this, you'd need to go through table_2 every time you change stuff in table_1, which is an extra database call.
Case 2. Internal consistency
Now let's say bob wants to change his name to jill. What happens now?
table_1 table_2
ID_1 | name | email ID_2 | name | email
1 | jill | bob#cat.com 1 | adam | adam#dog.com
2 | adam | adam#dog.com 2 | bob | bob#cat.com
3 | bob | bob#dog.com 3 | bob | bob#dog.com
4 | joe | joe#dog.com
Oops, I accidentally only updated one row corresponding to bob in table 1, now it seems like bob#cat.com and bob#dog.com are two different people, when they actually are the same. So I'd have to go through the entire database and check every row for name = "bob". Then I have to do the same for table_2. Your database is quickly becoming unmanageable.
Database Normalization
Instead of having two tables.
table_1 table_2
ID_1 | name | email ID_2 | name | email
1 | bob | bob#cat.com 1 | adam | adam#dog.com
2 | adam | adam#dog.com 2 | bob | bob#cat.com
3 | bob | bob#dog.com 3 | bob | bob#dog.com
4 | joe | joe#dog.com
Take the information common to the two tables, namely name-email pairs, and put it in a user table
table_1 table_2 user
ID_1 | userId ID_2 | userId userId | name | email
1 | 2 1 | 1 1 | adam | adam#dog.com
2 | 1 2 | 2 2 | bob | bob#cat.com
3 | 2 3 | 2 2 | bob | bob#dog.com
4 | 3 3 | joe | joe#dog.com
This fixes a lot of issues, now when you want to look up a user's name/email, you go look it up in a user table based off a userId. If adam changes his email, it changes for both tables (because they both refer to the user table).
There's still one more thing, if bob changes his name, we shouldn't have to look through the entire user table to change every occasion of his name. So we can take this one step further.
table_1 table_2 user email
ID_1 | userId ID_2 | userId userId | name userId | email
1 | 2 1 | 1 1 | adam 1 | adam#dog.com
2 | 1 2 | 2 2 | bob 2 | bob#cat.com
3 | 2 3 | 2 3 | joe 2 | bob#dog.com
4 | 3 3 | joe#dog.com
Now we have no pieces of information that are redundant, no need to duplicate values, and changes in any one place affects every other table that refers to it.
#remram: Thanks, it works. I tried directly with PhpMyAdmin.
Some small modification:
UPDATE table_2, table_1
SET table_2.`email` = table_1.`email`
WHERE table_1.`name` = table_2.`name`;
#HansZ: Thank you also for the DataBase Normalization explanation.
In this case, remram solution is what I was needing. I was looking for a kind of Fuzzy VLOOKUP in MySQL, and this would be a way to get what I want
http://denglishbi.wordpress.com/2011/05/15/microsoft-fuzzy-lookup-add-in-for-excel-2010-walkthrough/
And here a small Explanation: I have a list of words that needs to be translated. Some of those words are already in the Master, and the Slave database is empty... At the end, I just need to translate the empty values

migrate data from one table to another with parent child association

I am migrating data from table A to table B.
Table A has fields id, parent_id,title, credit.
Table B has fields id, parent_id, title, credit. where id is auto incremental field.
Table A has self association, where parent_id refers to a row in Table A itself.
From a rake task I need to migrate data from table A to table B.
sample data in table A:
id | parent_id | title | credit
12 | nil | ABC | 1
13 | 12 | XYZ | 1
14 | 12 | PQR | 0
15 | 13 | NOP | 1
after migrating data to table B, it should be like this:
id | parent_id | title | credit
1 | nil | ABC | 1
2 | 1 | XYZ | 1
3 | 1 | PQR | 0
4 | 2 | NOP | 1
When migrating data from table A to table B using ruby script, I can update title, credit with new id. How can I update parent_id?
Thanks for the support.
Update parent id after create. Something like this,
a = A.all
a.each { |v|
B.create!({parent_id: v.parent_id,title: v.title,credit: v.credit})
A.update_all({parent_id: B.last.id},{parent_id: v.parent_id})
}
I think so you need to update your ids as well.
table_b_obj.id = table_a_obj.id
table_b_obj.save!
table_b_obj.reload

mysql: how to split list field

I have a table which only contains id and a field whose data is a list of data. e.g.
--------------
| id | data |
| 1 | a,b,c,d|
| 2 | a,b,k,m|
---------------
I guess it's not a good design that put a list data in a field, so I want to know how can I redesign it?
As per me you need two tables i.e. Master and Transaction tables only when some details are gonna be same for every records and some are gonna be changing. In your case if there are not any other thing related to your id field is gonna be same you can carry on with one table and with following structure.
--------------
| id | data |
| 1 | a |
| 1 | b |
| 1 | c |
| 1 | d |
| 2 | a |
| 2 | b |
| 2 | k |
| 2 | m |
---------------
BUT if there are any other things related to the id fields that is gonna be same for same id records you will have to use two tables.
like following case. there are 3 fields id, name and data.
and you current table looks something like
--------------------------
| id | name | data |
| 1 | testname | a,b,c,d|
| 2 | remy | a,b,c,d|
--------------------------
your new table structure should look like.
table 1 Master
-----------------
| id | name |
| 1 | testname |
| 2 | remy |
-----------------
Table 2 Transaction
--------------
| id | data |
| 1 | a |
| 1 | b |
| 1 | c |
| 1 | d |
| 2 | a |
| 2 | b |
| 2 | k |
| 2 | m |
---------------
For better database management we might need to normalize the data.
Database normalization is the process of organizing the fields and tables of a relational database to minimize redundancy and dependency. Normalization usually involves dividing large tables into smaller (and less redundant) tables and defining relationships between them. The objective is to isolate data so that additions, deletions, and modifications of a field can be made in just one table and then propagated through the rest of the database via the defined relationships. You can find more on below links
3 Normal Forms Database Tutorial
Database normalization
If you have only those two fields in your table then you should have only 1 table as below
id | data
with composite primary key as PRIMARY KEY(id,data) so that there won't be any duplicate data for the respective ID.
The data would be like this
id | data
1 | a
1 | b
1 | c
1 | d
2 | a
2 | b
2 | k
2 | m
You will need another table which can be of the ONE to MANY type.
For e.g. you could have another table datamapping which would have data and ID column where the ID column is a FOREIGN KEY to the ID column of the data table.
So according to your example there would be 4 entries for ID = 1 in the datamapping table.
You will need two tables with a foreign key.
Table 1
id
Table 2
id
datavalue
So the data looks like:
Table 1:
id
1
2
3
Table 2:
id | data
1 | a
1 | b
1 | c
1 | d
2 | a
2 | b
2 | k
2 | m
You are correct, this this is not a good database design. The data field violates the principle of atomicity and therefore the 1NF, which can lead to problems in maintaining and querying the data.
To normalize your design, split the original table in two. There are 2 basic strategies to do it: using non-identifying and using identifying relationship.
NOTE: If you only have id in the parent table, and no other FKs on it, and parent cannot exist without at least one child (i.e. data could not have been empty in the original design), you can dispense with the parent table altogether.

Data Entry Tracking (Database Design)

I have developed a website (PHP) that allow staffs to add records on to our system.
Staffs will be adding thousands of records into our database.
I need a way to keep track of what record have been done and the process/status of record.
Here a number of Teams I could think of:
Data Entry Team
Proof Reading Team
Admin Team
When staff (Data Entry Team) completed a record - he/she will then click on the Complete button. Then somehow it should asssign to 'Proof Reading Team' automatically.
A record need to be checked twice from a Proof Reading Team. If StaffB finish proof reading then another member from Proof Reading Team need to check it again.
When Proof reading is done, Admin Team will then assign "Record Completed"
In a few months later record might need to be updated (spelling mistake, price change, etc) - Admin might to assign record to Data entry team.
Is this good data entry management solution? How do I put this into Database Design perspective?
Here what I tried:
mysql> select * from records;
+----+------------+----------------------+
| id | name | address |
+----+------------+----------------------+
| 1 | Bill Gates | Text 1 Text Text 1 |
| 2 | Jobs Steve | Text 2 Text 2 Text 2 |
+----+------------+----------------------+
mysql> select * from staffs;
+----+-----------+-----------+---------------+
| id | username | password | group |
+----+-----------+-----------+---------------+
| 1 | admin1 | admin1 | admin |
| 2 | DEntryA | DEntryA | data_entry |
| 3 | DEntryB | DEntryB | data_entry |
| 4 | PReadingA | PReadingA | proof_reading |
| 5 | PReadingB | PReadingB | proof_reading |
+----+-----------+-----------+---------------+
mysql> select * from data_entry;
+----+------------+-----------+------------------------+
| id | records_id | staffs_id | record_status |
+----+------------+-----------+------------------------+
| 1 | 2 | 3 | data_entry_processiing |
| 2 | 2 | 3 | data_entry_completed |
| 3 | 2 | 4 | proof_read_processing |
| 4 | 2 | 4 | proof_read_completed |
| 5 | 2 | 5 | proof_read_processing |
| 6 | 2 | 5 | proof_read_completed |
+----+------------+-----------+------------------------+
Is there alternative better solution of database design?
i think design it's well done. but may be you want to separate group into groups table, and record_status into status table. If you're storing a lot of records you would store a lot of useless information, at least create an enum type for record_status field and group field
table: groups
id - name 1 - admin 2 - data_entry 3 - proof_reading
...
table: status
id - name 1 - data_entry_processing ...
and if you want the users to be in different groups at a time, you could create users_group table
table: user_groups
group_id - user_id 1 - 1 2 - 1 1 - 4 3 -
4 4 - 4 ....
Hope this helps