Update table from another table throught intermediate table Mysql - mysql

I have the next table setup, two tables related by an intermediate table, like this:
Client
| client_id | ...|field_X |
| 1 | ...|value1 |
| 2 | ...|value2 |
| 3 | ...|value3 |
Project
| project_id | ...|field_X |
| 1 | ...| |
| 2 | ...| |
| 3 | ...| |
| 4 | ...| |
| 5 | ...| |
| 6 | ...| |
| 7 | ...| |
client_project
| client_id | project_id|
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
| 3 | 6 |
| 3 | 7 |
The field_x in the table project is new and i have to fill it with the data from table client to get approximately something like this:
Project
| project_id | ...|field_X |
| 1 | ...| |
| 2 | ...|value1 |
| 3 | ...|value1 |
| 4 | ...|value2 |
| 5 | ...|value2 |
| 6 | ...|value3 |
| 7 | ...|value3 |
i dont know hot to deal with the intermediate table. i have tried this code but it doesnt work.
INSERT INTO project
(field_x)
(select field_x
from
client_project
inner join
client
where client_project.client_id = client.client_id
);
I have the idea of what i have to do but i am not able to translate it into a sql command because of the intermeditate table.Could someone explain how to deal with it?
Thanks in advance.

I assume you already have all entries in the project table but they're missing the Field_X property? So what you need is an update, not an insert
UPDATE project p, client c, project_client pc SET p.Field_X=c.Field_X WHERE p.ID=pc.ProjectID AND c.ID=pc.ClientID
However, be advised that having the same data in two places is not a good practise; if possible always put one fact in only one place.

Related

I understand that the PIVOT command can transform a dataset, is this the correct way how to do it?

I have a dataset that looks like this:
+----+-------------+
| ID | StoreVisit |
+----+-------------+
| 1 | Home Depot |
| 2 | Lowes |
| 3 | Home Depot |
| 2 | ACE |
| 2 | Lowes |
| 1 | Home Depot |
| 4 | ACE |
| 5 | ACE |
| 4 | Lowes |
+----+-------------+
I'm new(ish) to SQL and I know I can select all and then either use Excel (pivot table / functions / paste special) or R (tidyr) to transpose.. however, if I have a lot of data, this is not efficient. Is the query below correct? If so, how can I define all values of StoreVisit if there are thousands of types of stores without typing each one in the query?
select * from Stores
pivot (COUNT(StoreVisit) for StoreVisit in ([ACE],[Lowes],[Home Depot])) as StoreCounts
+----+-------+-----------+-----+
| ID | Lowes | HomeDepot | ACE |
+----+-------+-----------+-----+
| 1 | 0 | 2 | 0 |
| 2 | 2 | 0 | 0 |
| 3 | 0 | 1 | 0 |
| 4 | 1 | 0 | 1 |
| 5 | 0 | 0 | 1 |
+----+-------+-----------+-----+
Please excuse the formatting of this post! Many apologies.
Use conditional aggregation:
select id,
sum(storevisit = 'Lowes') as lowes,
sum(storevisit = 'HomeDepot') as HomeDepot,
sum(storevisit = 'Ace') as ace
from t
group by id;

Conditionally move MySQL data between rows in same table

Working in Redmine, I need to copy(not move) data from certain rows to other rows based on matching project id numbers with time entries.
I have included a diagram of the table "custom_values" and my understanding of the design below(CURRENT DATA):
+----+-----------------+---------------+-----------------+-------+
| id | customized_type | customized_id | custom_field_id | value |
+----+-----------------+---------------+-----------------+-------+
| 1 | Project | 1 | 1 | 01 |
| 2 | TimeEntry | 1 | 4 | 01 |
| 3 | Project | 2 | 1 | 02 |
| 4 | TimeEntry | 2 | 4 | 02 |
| 5 | Project | 3 | 1 | 03 |
| 6 | TimeEntry | 3 | 4 | |
| 7 | Project | 4 | 1 | 04 |
| 8 | TimeEntry | 4 | 4 | |
+----+-----------------+---------------+-----------------+-------+
At the risk of oversimplifying,
"id" = The primary key for each entry in custom_values
"customized_type" = Specifies which db table the row is referring to.
"customized_id" = Specifies the primary key for the db table entry previously specified in "customized_type".
"custom_field_id" = Specifies which custom field the row is referring to. Redmine admins can arbitrarily add and remove custom fields.
"value" = The data contained within the custom field specified by
"custom_field_id"
In my situation, the values listed in "value" are representing unique customer id numbers. The customer id numbers did not always get entered with each time entry. I need to copy the customer numbers from the project rows to the matching time entry rows. Each time entry has a project_id field.
So far, here is my mangled SQL query:
SELECT
custom_field_id,
custom_values.value AS 'CUSTOMER_NUMBER',
custom_values.customized_id AS 'PROJECT_ID_NUMBER',
custom_values.customized_type,
time_entries.comments AS 'TIME_ENTRY_COMMENTS'
FROM
redmine_tweaking.custom_values
LEFT JOIN
redmine_tweaking.time_entries ON custom_values.customized_id = time_entries.project_id
WHERE
custom_values.customized_type='Project' AND custom_values.custom_field_id=1;
The query I have so far allows me to see that I have the time entries connected properly to their matching projects, but that is all I have been able to figure out. So in other words, this SQL statement does not exactly solve my problem.
Plus, even if it did work, I think the way I laid it out looks like 200 lbs of bird poop. There must be a better/more optimized way to do this.
Any help would be greatly appreciated. I am relatively new and I have been pouring hours into solving this problem.
UPDATE:
Ok, here is the time_entries table:
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
| id | project_id | user_id | issue_id | hours | comments | activity_id | spent_on | tyear | tmonth | tweek | created_on | updated_on |
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
| 1 | 1 | 1 | 1 | .25 | test | 9 | 2015-11-04 | 2015 | 11 | 45 | 2015-11-04 08:18:12 | 2015-11-04 10:18:12 |
| 2 | 2 | 1 | 1 | .25 | test2 | 9 | 2015-11-04 | 2015 | 11 | 45 | 2015-11-04 09:18:12 | 2015-11-04 12:18:12 |
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
As opposed to the original table that I first posted, the expected output would show this:
+----+-----------------+---------------+-----------------+-------+
| id | customized_type | customized_id | custom_field_id | value |
+----+-----------------+---------------+-----------------+-------+
| 1 | Project | 1 | 1 | 01 |
| 2 | TimeEntry | 1 | 4 | 01 |
| 3 | Project | 2 | 1 | 02 |
| 4 | TimeEntry | 2 | 4 | 02 |
| 5 | Project | 3 | 1 | 03 |
| 6 | TimeEntry | 3 | 4 | 03 |
| 7 | Project | 4 | 1 | 04 |
| 8 | TimeEntry | 4 | 4 | 04 |
+----+-----------------+---------------+-----------------+-------+

SQL INSERT INTO query syntax

I am trying to run an MySQL query to copy over data from an old table (ps__product_review/rate) to a new table (ps_product_comment/grade) based on review ID (id_product_comment). But I am a bit lost on the SQL query, this is what I have but keep getting errors.
INSERT INTO ps_product_comment [(grade)]
SELECT rate
FROM ps__product_review
[WHERE ps__product_review.id_product_comment=ps_product_comment.id_product_comment];
Can anyone help write the correct query?
Edit:Essentially I am trying to populate the Grade column in the new table below.
Old table (ps__product_review)
+--------------------+----------+-----+
| id_product_comment | Comment | Rate|
+--------------------+----------+-----+
| 1 | Good | 2 |
| 2 | Great | 5 |
| 3 | OK | 3 |
| 4 | Brill | 4 |
| 5 | OK | 3 |
| 6 | Average | 2 |
| 7 | Bad | 1 |
+--------------------+----------+-----+
New Table (ps_product_comment)
+--------------------+----------+-------+
| id_product_comment | Comment | Grade |
+--------------------+----------+-------+
| 1 | Good | |
| 2 | Great | |
| 3 | OK | |
| 4 | Brill | |
| 5 | OK | |
| 6 | Average | |
| 7 | Bad | |
+--------------------+----------+-------+
If you want to update table with data from another table, use UPDATE with JOIN
UPDATE ps_product_comment
JOIN ps__product_review
ON ps__product_review.id_product_comment = ps_product_comment.id_product_comment
SET ps_product_comment.grade = ps__product_review.rate;
Remove the square brackets and I think you are missing the JOIN(since you are using that in your where clause):
INSERT INTO ps_product_comment (grade)
SELECT rate
FROM ps__product_review inner join ps_product_comment on
ps__product_review.id_product_comment=ps_product_comment.id_product_comment;

Correct SQL statement for 3 tables query

Please be assured that I searched a lot on SE for an answer similar to mine but didn't get any good result and here I am asking for some help.
I have 3 tables as follows:
Table Professors:
+---------+--------+
| idProf | name |
+---------+--------+
| 1 | Ben |
| 2 | John |
| 3 | Bob |
+---------+--------+
Table Classes:
+---------+--------+------------+
| idClass | name | profRefId |
+---------+--------+------------+
| 1 | French | 1 |
| 2 | English| 1 |
| 3 | German | 3 |
| 4 | Science| 2 |
+---------+--------+------------+
Table Lessons:
+----------+----------+--------------+
| idLesson | name | classRefId |
+----------+----------+--------------+
| 1 | Lesson1 | 1 |
| 2 | Lesson2 | 1 |
| 3 | Lesson3 | 2 |
| 4 | Lesson4 | 4 |
| 5 | Lesson5 | 4 |
| 6 | Lesson6 | 3 |
+----------+----------+--------------+
Now, what I was struggling to achieve is:
I pass idProf as a URL parameter ($_GET['idProf'])
And I would like the right SQL statement based on that param to list all the classes for that professor and inside each class list its lessons.
Something that will look like this on a webpage:
Something like this?
SELECT a.name ProfessorName, b.name ClassName, c.name LessonName
FROM Professors a
INNER JOIN Classes b
ON a.idProf=b.profRefID
INNER JOIN Lessons c
ON b.idClass=c.classRefID

MySQL - Use Header Name as Part of Query Filter

I'm relatively new to MySQL and have come across a problem to which I cannot seem to find a solution. I have searched but could not find an answer. I'm open to the possibility that I'm not asking the question correctly. Here goes:
I'm trying to use the name of a given column and the values within that column from one table to pull values from another table. The first table contains 3 columns with the response codified. The second table contains the definitions for each code for each item. The same number code is associated with different meanings depending on the item. For example:
table1 (this table cannot change):
--------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------
| 1 | j | doe | 1 | 3 | 2 |
| 2 | k | smith | 3 | 1 | 2 |
| 3 | l | williams | 2 | 2 | 1 |
--------------------------------------------------------------
table2 (this table can be modified, split, or whatever needs to be done):
-------------------------------------------
|item_id | item_name | score | definition |
-------------------------------------------
| 1 | item_A | 1 | agree |
| 2 | item_A | 2 | neutral |
| 3 | item_A | 3 | disagree |
| 4 | item_B | 1 | likely |
| 5 | item_B | 2 | not likely |
| 6 | item_B | 3 | no reply |
| 7 | item_C | 1 | yes |
| 8 | item_C | 2 | no |
-------------------------------------------
My goal is for the query to output the following:
--------------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------------
| 1 | j | doe | agree | no reply | no |
| 2 | k | smith | disagree | likely | no |
| 3 | l | williams | neutral | not likely | yes |
--------------------------------------------------------------------
Any assistance or guidance is greatly appreciated. Thank you in advance.
You must join the two tables on the item_A/B/C and score columns
select t1.result_id, t1.f_initial, t1.l_name,
t2a.definition as item_a,
t2b.definition as item_b,
t2c.definition as item_c
from table1 t1
join table2 t2a on t2a.score = t1.item_a
join table2 t2b on t2b.score = t1.item_b
join table2 t2c on t2c.score = t1.item_c
where t2a.item_name = 'item_A'
and t2b.item_name = 'item_B'
and t2c.item_name = 'item_C'