INSERT into Mysql table from table2, comparing variables in both tables - mysql

Ok, I have two tables, Region and Cities and I need to link them together using the id from regions. At present a common code is used which does not work for my use case.
Region Table:
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| country_code | varchar(255) | NO | MUL | NULL | |
| code | varchar(255) | NO | | NULL | |
| name | varchar(255) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
City Table
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| country_code | varchar(255) | NO | MUL | NULL | |
| name | varchar(255) | NO | | NULL | |
| state | varchar(255) | NO | | NULL | |
| ascii_name | varchar(255) | NO | | NULL | |
| latitude | double | NO | | 0 | |
| longitude | double | NO | | 0 | |
| timezoneid | varchar(255) | NO | | NULL | |
| region_id | int(11) | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
In the City table, I have added the int region_id and I would like to populate it from the region table based on some city.country_code = region.country_code AND region.code = city.state.
Something along these lines:
INSERT INTO city (region_id) SELECT id FROM region WHERE city.country_code = region.country_code AND city.state = region.code;
That's the essence of what I am trying to do, MySql work is not a strong point.
Any help, appreciated!

I think you want an update statement (that modifies data on existing rows) rather than an insert (which creates new rows).
If so, you can use MySQL's update ... join syntax:
update city c
inner join region r
on c.country_code = r.country_code
and c.state = r.code
set c.region_id = r.id

Related

Don't know how to GROUP_BY my data

Here is a description of my tables
describe book;
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| isbn | varchar(20) | NO | PRI | NULL | |
| title | varchar(30) | YES | | NULL | |
| date_published | date | YES | | NULL | |
| publisher_id | int(11) | YES | | NULL | |
+----------------+-------------+------+-----+---------+-------+
describe author;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| author_id | int(11) | NO | PRI | NULL | |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(20) | YES | | NULL | |
+------------+-------------+------+-----+---------+-------+
describe stored_on;
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| isbn | varchar(20) | YES | | NULL | |
| total_copies | int(11) | YES | | NULL | |
| shelf_number | int(11) | YES | | NULL | |
| library | varchar(20) | YES | MUL | NULL | |
+--------------+-------------+------+-----+---------+-------+
describe written_by;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| isbn | varchar(20) | YES | MUL | NULL | |
| author_id | int(11) | YES | MUL | NULL | |
+-----------+-------------+------+-----+---------+-------+
I am trying to display book name, list of authors that wrote that book, shelf number, total copies, and the library the book is located at.
SELECT
b.title,
GROUP_CONCAT(CONCAT_WS(' ',a.first_name, a.last_name )) AS authors,
so.shelf_number,
so.total_copies,
so.library
FROM
stored_on so
LEFT OUTER JOIN book b ON so.isbn = b.isbn
LEFT OUTER JOIN written_by wb ON wb.isbn = so.isbn
LEFT OUTER JOIN author a ON wb.author_id = a.author_id
GROUP BY (b.title);
I don't know how to group my data at the end in a way that will give me duplicate titles/isbn.
Example: There is a book at one library, and the same book at another library, I want to print out the data for each one. They are all listed in my stored_on table to begin with, and I can print out all of the entries when I don't use GROUP_CONCAT, but I do get double entries in the authors field.
Cannot seem to figure this one out.

SQL How to list the NULL values once output is generated for another table

I am new to SQL and I am having the below doubt-
3 tables:
mysql> describe course;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| course_id | varchar(8) | NO | PRI | | |
| title | varchar(50) | YES | | NULL | |
| dept_name | varchar(20 ) | YES | MUL | NULL | |
| credits | decimal(2,0) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
mysql> describe section;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| course_id | varchar(8) | NO | PRI | | |
| sec_id | varchar(8) | NO | PRI | | |
| semester | varchar(6) | NO | PRI | | |
| year | decimal(4,0) | NO | PRI | 0 | |
| building | varchar(15) | YES | MUL | NULL | |
| room_number | varchar(7) | YES | | NULL | |
| time_slot_id | varchar(4) | YES | | NULL | |
| capacity | int(11) | YES | | 30 | |
+--------------+--------------+------+-----+---------+-------+
describe department;
+-----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| dept_name | varchar(20) | NO | PRI | | |
| building | varchar(15) | YES | | NULL | |
| budget | decimal(12,2) | YES | | NULL | |
+-----------+---------------+------+-----+---------+-------+
The question is "List the total number of sections is being offered by each department in Spring 2008."
I have tried the below query:
SELECT dept_name,SUM(sec_id) AS Total_offerings
FROM section natural
left outer join course
WHERE semester='Spring' and year=2008
GROUP By dept_name;
But the result does not contains the department names with Null values.
Can anyone help me in how to add the department names in the output even if they were not taught in Spring 2008 with NULL values
The output looks like this:
+-------------+----------------+
| dept_name | total_offering |
+-------------+----------------+
| Accounting | 7 |
| Astronomy | 4 |
For LEFT JOIN You need to put the filter on the join condition otherwise is just a normal INNER JOIN
SELECT dept_name, COUNT(sec_id) AS Total_offerings
FROM department
JOIN course
ON department.dept_name = course.dept_name
LEFT JOIN section
ON section.course_id = course.course_id
AND section.semester = 'Spring'
AND section.year = 2008
GROUP By dept_name;
For MySQL use IFNULL and for SQL Server use ISNULL
SELECT ISNULL(dept_name,'Blank Dept Name'),SUM(sec_id) AS Total_offerings
FROM section natural left outer join course WHERE semester='Spring' and year=2008
GROUP By ISNULL(dept_name,'Blank Dept Name');

Update MySQL table based on results for joining to tables

I have three tables, emails, person_details and data_providers. Basically all of my users id, email, and current assigned data_providers_id are stored in the emails table.
The second table, person_details contains demographic information collected by multiple data providers, each row identified by an emails_id that is relational to the emails.id data_providers_id that is relational to the third table data_providers.id
The third table, data_providers contains each of my data providers id, name, and precedence.
Basically, a users information could be collected from multiple sources, and I need to UPDATE emails set data_providers_id = based on a select that would JOIN the person_details table and the data_providers table sorting by data_providers.precedence DESC then person_details.import_date ASC and use the first value (highest precedence, then oldest import_date).
I was trying to build the query, but my subquery is returning more than one row. This query is a little over my head, hoping someone more experienced with complex queries might be able to point me in the right direction.
UPDATE emails
SET emails.data_providers_id =
SELECT person_details.data_providers_id
FROM person_details
LEFT JOIN data_providers ON person_details.data_providers_id = data_providers.id
ORDER BY data_providers.percent_payout ASC, person_details.import_date ASC ;
Here are some details about the three tables if this helps. Any guidance would be MUCH appreciated. Thanks in advance :)
emails table:
+-------------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------+------+-----+---------------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| data_providers_id | tinyint(3) unsigned | NO | MUL | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
+-------------------+---------------------+------+-----+---------------------+----------------+
person_details:
+-------------------+---------------------+------+-----+---------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------+------+-----+---------------------+-------+
| emails_id | int(11) unsigned | NO | PRI | NULL | |
| data_providers_id | tinyint(3) unsigned | NO | PRI | NULL | |
| fname | varchar(255) | YES | | NULL | |
| lname | varchar(255) | YES | | NULL | |
| address_line1 | text | YES | | NULL | |
| address_line2 | text | YES | | NULL | |
| city | varchar(255) | YES | | NULL | |
| state | varchar(2) | YES | | NULL | |
| zip5 | varchar(5) | YES | | NULL | |
| zip4 | varchar(4) | YES | | NULL | |
| home_phone | varchar(10) | YES | | NULL | |
| mobile_phone | varchar(10) | YES | | NULL | |
| work_phone | varchar(10) | YES | | NULL | |
| dob | date | YES | | NULL | |
| gender | varchar(1) | YES | | NULL | |
| ip_address | varchar(15) | NO | | NULL | |
| source | varchar(255) | NO | | NULL | |
| optin_datetime | datetime | NO | MUL | NULL | |
| import_date | timestamp | NO | | 0000-00-00 00:00:00 | |
+-------------------+---------------------+------+-----+---------------------+-------+
data_providers table:
+-----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+----------------+
| id | tinyint(3) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| precedence | int(2) | YES | | 0 | |
+-----------------+---------------------+------+-----+---------+----------------+
To use a SELECT as an expression you have to put it in parentheses. And to get the first value, use LIMIT 1:
UPDATE emails
SET emails.data_providers_id = (
SELECT person_details.data_providers_id
FROM person_details
LEFT JOIN data_providers ON person_details.data_providers_id = data_providers.id
WHERE person_details.emails_id = emails.id
ORDER BY data_providers.percent_payout ASC, person_details.import_date ASC
LIMIT 1) ;

sql joining three tables using inner joins

in my database I have 3 tables named items, manufacturers and items_manufacturers. manufacturers has a HAS:MANY relation with items_manufacturers
My items table
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| code | varchar(25) | NO | MUL | NULL | |
| item_category | varchar(100) | NO | | NULL | |
| item_desc | varchar(500) | NO | | NULL | |
| reorder_point | int(11) | NO | | NULL | |
| unit | varchar(45) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
My manufacturers table
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| code | varchar(25) | NO | | NULL | |
| name | varchar(250) | NO | | NULL | |
| address | varchar(750) | NO | | NULL | |
| contact_no | varchar(50) | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
My items_manufacturers table
+-----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| item_id | bigint(20) | NO | MUL | NULL | |
| manufacturer_id | bigint(20) | NO | MUL | NULL | |
| unit_cost | decimal(20,2) | NO | | NULL | |
| vendor_id | bigint(20) | NO | | NULL | |
+-----------------+---------------+------+-----+---------+----------------+
In my result table I want items_id, items_desc, name of manufacturer from manufacturers table and manufacturer_id. The relation I have is
items.id=items_manufacturers.item_id and
manufacturers.id=items_manufacturers.manufacturer_id.
I tried using inner joins for three tables but not working.
The query I tried
select
items_manufacturers.id,
items.item_desc,
item_manufacturers.manufacturer_id,
manufacturer.name
from items_manufacturers
INNER JOIN items ON items_manufacturers.item_id=items.id
INNER JOIN manufacturers ON items_manufacturers.manufacturer_id=manufacturers.id
Anybody kindly help me with this, I am stuck up from a long time
I used this following code and got the result you were trying to get. This code may solve your problem:
select a.name,b.manufacturer_id,c.id,c.item_desc
from manufacturers as a
inner join
item_manufacturers as b
on b.manufacturer_id=a.id
inner join item as c
on c.id=b.item_id

Why isn't this JOIN working?

Database Tables
ss_merchant
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| pk_merchant_id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(45) | YES | | NULL | |
| website | varchar(100) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
ss_merchant_store
+----------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+-------------+------+-----+---------+----------------+
| pk_merchant_store_id | bigint(20) | NO | PRI | NULL | auto_increment |
| fk_pk_merchant_id | bigint(20) | YES | | NULL | |
| street | varchar(20) | YES | | NULL | |
| city | varchar(20) | YES | | NULL | |
| postcode | varchar(8) | YES | | NULL | |
| telephone | varchar(15) | YES | | NULL | |
| email | varchar(45) | YES | | NULL | |
+----------------------+-------------+------+-----+---------+----------------+
ss_merchant_store_rating
+-----------------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+------------+------+-----+---------+----------------+
| pk_merchant_store_rating_id | bigint(20) | NO | PRI | NULL | auto_increment |
| fk_pk_merchant_store_id | bigint(20) | NO | | NULL | |
| rating | int(1) | YES | | NULL | |
+-----------------------------+------------+------+-----+---------+----------------+
and my query:
SELECT *
FROM ss_merchant
JOIN ss_merchant_stores
ON ss_merchant.pk_merchant_id = ss_merchant_stores.fk_pk_merchant_id
JOIN ss_merchant_store_rating
ON ss_merchant_stores.pk_merchant_store_id = ss_merchant_store_rating.fk_pk_merchant_store_id
There isn't anything specifically wrong with your join but it does make the assumption that all three tables have at least one row for each merchant_id. If you want to allow for non-existant merchant_store_rating rows consider using a LEFT JOIN
If there is no matching row for the
right table in the ON or USING part in
a LEFT JOIN, a row with all columns
set to NULL is used for the right
table. You can use this fact to find
rows in a table that have no
counterpart in another table:
SELECT left_tbl.* FROM left_tbl LEFT JOIN right_tbl
ON left_tbl.id = right_tbl.id WHERE right_tbl.id IS NULL;
This example finds all rows in
left_tbl with an id value that is not
present in right_tbl (that is, all
rows in left_tbl with no corresponding
row in right_tbl). This assumes that
right_tbl.id is declared NOT NULL.