MySQL - Update table values from another table - mysql

I have two tables -
subjects and questions.
Structure and rows of table subjects are like :-
----------------------------
subject_id | subject_name
----------------------------
1 | physics
2 | chemistry
3 | biology
Structure and rows of table questions are like :-
question_id | subject_id | subject_name | question
---------------------------------------------------------
1 | 0 | physics | demo_question_1
2 | 0 | physics | demo_question_2
3 | 0 | chemistry | demo_question_3
4 | 0 | biology | demo_question_4
I added column subject_id in questions table after I had already inserted some rows. I want to bulk update subject_id of questions table as per subjects table. I can update them individually, using WHERE, but I was hoping if any single query would do this work?

Not sure what you mean by a single query versus a WHERE, but I think this will suit your needs.
UPDATE questions q, subjects s
SET q.subject_id = s.subject_id
WHERE q.subject_name = s.subject_name;

Related

Select all values from a table plus a column returning 1/0 whether a record exists in other table [duplicate]

This question already has answers here:
Selecting boolean in MySQL based on contents of another table
(2 answers)
Closed 4 years ago.
I need some help with a MySQL query which is bringing me a headache.
Basically I have two tables which are related. The first table is called 'books' and it contains the basic information about a book. Then I have an other table called 'user_books' which is related to the previous table and other table (which is irrelevant in the question). This is how the books table looks like:
| b_id | b_name | b_description |
---------------------------------------------------
| 1 | Book1 | Description1 |
| 2 | Book2 | Description2 |
The 'user_books' table has this content:
| ub_userid | ub_bookid | ub_rating | ub_default |
------------------------------------------------------
| 10 | 1 | 5 | 1 |
The user_books table has two primary keys: ub_userid and ub_bookid.
Now I need to make a query which returns all books of the books table and for each book the rating of a given user and a column that in case that there is a record for the book in the user_books table return 1 but if there isn't any book with that bookid return 0.
My desired output given the user 10 would be this:
| b_id | b_name | b_description | ub_default | active |
----------------------------------------------------------
| 1 | Book1 | Description1 | 1 | 1 |
| 2 | Book2 | Description2 | 0 | 0 |
----------------------------------------------------------
I'm using MySQL 5.7
Thanks so much in advance for any kind of help.
select
b.b_id,
b.b_name,
b.b_description,
coalesce(ub.ub_default, 0) as ub_default,
case
when ub.ub_userid is null then 0
else 1
end as active
from books b left outer join
user_books ub
on ub.ub_bookid = b.b_id
where
ub.ub_userid = 10;
This doesn't do any aggregation, so if you have multiple user_books records for one books record, then the books record will be duplicated. But, it shows how to join against a missing row (outer join) and test for whether that outer join row is present or missing.
Here's a SQL Fiddle for MySQL 5.6 http://sqlfiddle.com/#!9/b70ff8/4/0

Get row values from foreign key MySQL

This may sound simple and dumb but how can I get the values of a foreign key from a table and displaying it?
I have a table named "subjects" which contains different school subjects and one column of it is a foreign key referencing from table named "faculty".
TABLE subjects
___________________________________
| sub_id | sub_faculty | sub_desc |
| 1 | 2 | PHYSICS |
| 2 | 3 | MATH |
| 3 | 4 | HISTORY |
|________|_____________|__________|
TABLE faculty
________________________
| fac_id | fac_name |
| 2 | John |
| 3 | Mark |
| 4 | Johnny |
|________|_____________|
I firstly wanted to check if data exist in the "subject" table and then proceed on displaying the row values of the foreign key.
I have this not so working query as displays both JOHN and JOHNNY. I was using LIKE as it will be for the search feature of the system so hopefully you can help me out on this.
SELECT *
FROM subject, faculty
WHERE subject.sub_desc = 'PHYSICS'
AND subject.sub_year = '4'
AND faculty.fac_name LIKE '%JOHN%'
GROUP BY faculty.fac_id
SELECT *
FROM subject s
join faculty f
on s.sub_faculty = f.fac_id
WHERE s.sub_desc = 'PHYSICS'
AND s.sub_year = '4'
AND f.fac_name LIKE '%JOHN%'

Update query using select -- how does it know which row to update

I have the following query that is working correctly but I don't understand why. I am changing the balance column for each row..How does it know which row to update for a particular customer.
UPDATE phppos_customers SET balance =
IFNULL((SELECT SUM(transaction_amount)
FROM `phppos_store_accounts`
WHERE deleted = 0 and customer_id = phppos_customers.person_id), 0);
For the sake of example, lets say you have the following two tables
[Users]
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | patrick |
| 2 | chris |
+---------+----------+
[Names]
+---------+------------+-----------+
| user_id | first_name | last_name |
+---------+------------+-----------+
| 1 | Patrick | Stewart |
| 2 | Chris | Angel |
+---------+------------+-----------+
If you had a update query like the one in your original post, you would want to tell it how to align the two tables. If you had the clause WHERE Users.user_id = Names.user_id, you are effectively telling SQL to view the data as if both tables were aligned side by side, using the user_id in both tables to determine where they match up. This would mean the first_name and last_name in the [Names] table for user_id 1 will be what is used when updating the row in the [Users] table that is user_id 1. It is essentially viewing the data merged together, like this:
[Users] and [Names] tables aligned by the user_id columns
+---------+----------+---------+------------+-----------+
| user_id | username | user_id | first_name | last_name |
+---------+----------+---------+------------+-----------+
| 1 | patrick | 1 | Patrick | Stewart |
| 2 | chris | 2 | Chris | Angel |
+---------+----------+---------+------------+-----------+
So when SQL is doing the updating, it updates each row with the corresponding data from the other table, using this aligning to know which data to use for each rows update.
The process of aligning/merging data from multiple tables is called joining in SQL, here is some more information that illustrates how it works if you are interested.

database design -- many to many table - how to best represent

I need to represent a many-to-many relationship between teachers and the subjects that they teach.
For implementation, a couple of strategies come to mind:
teacher_name | subject_names
bill math, english, science, french
sally | chemistry, english, arts & crafts
I've rejected this strategy because querying fields with comma separated values does not seem efficient, especially when I will be pulling them for search engines, iteration, etc... though I am certainly open to hearing a defense of this strategy
teacher_name | subject_name
bill math
bill english
bill science
... ...
sally chemistry
sally english
... ...
I initially thought this was a better idea, but when I query for information about the teacher, I get data that gets hard to report. i.e. it's fine that I have 5 rows for bob's subjects, but it's not fine that I also find that he lives at 123 main st. and 123 main st. and 123 main st... I still think this is a better idea overall, but maybe a better one exists.
By the way, I don't really use teacher_names and subject_names to index through, I use numbers, but I've drawn it this way for clarity
Many-to-many relationships are best solved using a third table called a Junction Table that maps the relations. Here's a good guide that explains a little more in detail, but basically...
The new table table will contain two columns of foreign keys; the unique ID (primary key of the teachers-table) of your teachers in one column, and subjects unique ID (primary key of the subjects-table) in the the other column (... and of course a column for the junction table's it's own unique ID).
Say this is your table of teachers:
----------------------------
| ID | Name | Last_Name |
----------------------------
| 0001 | JOHN | STEPHENS |
----------------------------
| 0002 | BRUCE | WAYNE |
----------------------------
And this is your table of subjects
-----------------------
| ID | Subject_name |
-----------------------
| 0101 | MATH |
-----------------------
| 0202 | BIOLOGY |
-----------------------
| 0303 | ENGLISH |
-----------------------
Then you need a junction table like this:
TeacherSubject_JunctionTable:
--------------------------------
| ID | Teacher_ID | Subject_ID |
--------------------------------
| 01 | 0001 | 0101 |
--------------------------------
| 02 | 0001 | 0202 |
--------------------------------
| 03 | 0002 | 0101 |
--------------------------------
| 04 | 0002 | 0303 |
--------------------------------
Now, whenever you need to get a list of teachers that teach math (subject_id 0101), you can simply query the juction table; something like
SELECT Teacher_ID FROM TeacherSubject_JunctionTable
WHERE Subject_ID = 0101;
Or the other way around, if you want to get the subjects that a teacher teach.
You can have a table for subjects (id,subject_name) another for teachers (id,teacher_name) and another table called teacher_subject that has teacher_id,subject_id as a composite key. this is the most recommended approach for many to many relationships as it is normalized.
Both of your solutions break normalization stratagies
The normal way to do this is with a 3rd Join Table.
teacher_ID | teacher_name | Other stuff about teachers
1 | bill | address, dob etc.
2 | sally | etc.
subject_ID | subject_name | Other stuff about teachers
1 | math | department, campus etc.
2 | english | etc.
teacher_ID | subject_ID | Other stuff about the relationship
1 | 4 | location etc.
1 | 2 | etc.
2 | 2 | etc.
2 | 1 | etc.
The teacher_ID & subject_ID is an auto-incrementing int primary key in the first 2 tables.
teacher_ID & subject_ID are the primary key of the 3rd.

HTML listing of recordset, resulting from a join on two tables that relate one-many

I have two tables, that relate via a one-to-many relationship i.e
tableOne (1)----------(*) tableTwo
Given the basic schema below
tableOne {
groupID int PK,
groupTitle varchar
}
and
tableTwo {
bidID int PK,
groupID int FK
}
Consider the two tables yield the following record-set based on joining the tables on the tableOne.groupID = tableTwo.groupID,
tableOne.groupID | tableOne.groupTitle | tableTwo.bidID | tableTwo.groupID
________________________________________________________________________________
1 | Physics Group | 1 | 1
2 | Chemistry Group | 2 | 2
2 | Chemistry Group | 3 | 2
1 | Physics Group | 4 | 1
I would like to list such a record-set in an HTML table as follows:
tableOne.groupID | tableOne.groupTitle | tableTwo.bidID | tableTwo.groupID
________________________________________________________________________________
1 | Physics Group | 1 | 1
| Physics Group | 4 | 1
2 | Chemistry Group | 2 | 2
| Chemistry Group | 3 | 2
I'm interested in finding out if this can be done in SQL, or alternatively finding out ways of listing such a record-set in HTML using good standards.
The solution that comes to mind is simply iterating through the record-set and leveraging a sentinel to list all records with the same tableOne.groupID grouped in a single row <tr> - and also listing tableOne.groupIDs once as a unique identifier of that record-group. However I don't want to go down that path as I would like to avoid mixing code with HTML if possible.
You can order the sql results using the ORDER BY clause.
So if you add
ORDER BY tableOne.groupID ASC, tableTwo.bidID ASC
in your query, you are half-way there.
Next step is to loop and print the recordset from your asp page, but also check if the last groupID is different than the current, in order to decide whether to show it or not..