How to display data from both tables - mysql

mysql> desc customer_delivery_loc;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| cust_loc_id | int(11) | NO | PRI | NULL | auto_increment |
| customer_id | int(11) | YES | MUL | NULL | |
| locality | varchar(100) | YES | | NULL | |
| area | varchar(100) | YES | | NULL | |
| address | varchar(100) | YES | | NULL | |
| city | varchar(50) | YES | | NULL | |
| state | varchar(50) | YES | | NULL | |
| phone_number | bigint(20) | YES | | NULL | |
| +---------------+--------------+------+-----+---------+----------------+
mysql> desc vendor_home_delivery;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| vendor_id | varchar(50) | YES | MUL | NULL | |
| locality | varchar(100) | YES | | NULL | |
| area | varchar(100) | YES | | NULL | |
| address | varchar(100) | YES | | NULL | |
| city | varchar(50) | YES | | NULL | |
| state | varchar(50) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
I have got two Tables as shown above
The area column is common for both the tables .
From User Interface area and phone_number will be passed .
How to write a query to display the data from both the tables based on phone_number and area ??
I tried this way but i am not sure and its giving error
select c.phone_number
from customer_delivery_loc c
where c.area in (select locality , address , area from vendor_home_delivery )
where c.phone_number = '9848032919';
- MySQL Database Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where c.phone_number = '9848032919'' at line 1

You need
and c.phone_number
in place of
where c.phone_number
in your query.

As one mistake pointed by already by #Ollie Jones for another error Operand should contain 1 column(s) error you can rewrite your query by using join
select c.phone_number
from customer_delivery_loc c
join vendor_home_delivery v
on(c.area = v.locality or c.area=v.address or c.area=v.area)
where c.phone_number = '9848032919';
Cause of this error is because you are comparing single column area with 3 columns using in()

Related

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

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

MySQL Unknown column in where clause?

I have two databases.
One is called INFO with three tables (Stories, Comments, Replies)
Stories has the following fields
+--------------+----------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------------+------+-----+---------------------+-----------------------------+
| storyID | int(11) | NO | PRI | NULL | |
| originalURL | varchar(500) | YES | | NULL | |
| originalDate | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| numDiggs | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| diggURL | varchar(500) | YES | | NULL | |
| rating | varchar(50) | YES | | NULL | |
| title | varchar(200) | YES | | NULL | |
| summary | varchar(10000) | YES | | NULL | |
| uploaderID | varchar(50) | YES | | NULL | |
| imageURL | varchar(500) | YES | | NULL | |
| category1 | varchar(50) | YES | | NULL | |
| category2 | varchar(50) | YES | | NULL | |
| uploadDate | timestamp | NO | | 0000-00-00 00:00:00 | |
| num | int(11) | YES | | NULL | |
+--------------+----------------+------+-----+---------------------+-----------------------------+
Another database is called Data with one table (User). Fields shown below:
+-------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+-------+
| userID | varchar(50) | NO | PRI | NULL | |
| numStories | int(11) | YES | | NULL | |
| numComments | int(11) | YES | | NULL | |
| numReplies | int(11) | YES | | NULL | |
| numStoryDiggs | int(11) | YES | | NULL | |
| numCommentReplies | int(11) | YES | | NULL | |
| numReplyDiggs | int(11) | YES | | NULL | |
| numStoryComments | int(11) | YES | | NULL | |
| numStoryReplies | int(11) | YES | | NULL | |
+-------------------+-------------+------+-----+---------+-------+
User.userID is full of thousands of unique names. All other fields are currently NULL. The names in User.userID correspond to the names in Stories.uploaderID.
I need to, for each userID in User, count the number of stories uploaded from (i.e. num) Stories for the corresponding name and insert this value into User.numStories.
The query which I have come up with (which produces an error) is:
INSERT INTO DATA.User(numStories)
SELECT count(num)
FROM INFO.Stories
WHERE INFO.Stories.uploaderID=DATA.User.userID;
The error I get when running this query is
Unknown column 'DATA.User.userID' in 'where clause'
Sorry if this is badly explained. I will try and re-explain if need be.
You aren't creating new entries in the User table, you're updating existing ones. Hence, insert isn't the right syntax here, but rather update:
UPDATE DATA.User u
JOIN (SELECT uploaderID, SUM(num) AS sumNum
FROM INFO.Stories
GROUP BY uploadedID) i ON i.uploaderID = u.userID
SET numStories = sumNum
EDIT:
Some clarification, as requested in the comments.
The inner query sums the num in Stories per uploaderId. The updates statement updates the numStories in User the the calculated sum of the inner query of the matching id.

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) ;

MySQL JOIN syntax precedence

I have two tables
members
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| mindex | smallint(4) | NO | PRI | NULL | auto_increment |
| memberid | smallint(5) | YES | MUL | NULL | |
| forenames | varchar(40) | YES | | NULL | |
| surname | varchar(20) | YES | | NULL | |
| nameprefix | varchar(30) | YES | | NULL | |
| namesuffix | varchar(50) | YES | | NULL | |
| died | smallint(5) | YES | | NULL | |
| notes | text | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
and
memberships;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| mshipindex | smallint(4) | NO | PRI | NULL | auto_increment |
| memberid | smallint(5) | YES | MUL | NULL | |
| msid | smallint(5) | YES | | NULL | |
| mstype | varchar(20) | YES | | NULL | |
| msyear | smallint(5) | YES | | NULL | |
| msposition | varchar(15) | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
I want to search on memberships for a year (in memberships.msyear) and get memberships.mstype and members.surname.
I just can't get the right JOIN syntax on this.
You will use something like this:
select m.surname,
s.mstype
from members m
left join memberships s
on m.memberid = s.memberid
where s.msyear = yourYear
See SQL Fiddle with Demo
I used a LEFT JOIN to return the all members, even those who might not have a membership record. If the member does not have a record in the memberships table, then it will return null.
If you need help learning JOIN syntax, here is a great visual explanation of joins
If you just need the syntax Here it is :
Select *
from members m
inner join membership ms on (m.memberid = ms.memberid)
where memberships.msyear = 2012

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.