Given the following tables
mysql> describe customers;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| customer_id | int(11) | NO | PRI | NULL | auto_increment |
| login | varchar(16) | NO | | NULL | |
| password | varchar(40) | NO | | NULL | |
| name | varchar(32) | NO | UNI | NULL | |
| address | varchar(64) | NO | | NULL | |
| contact | varchar(32) | NO | | NULL | |
+-------------+-------------+------+-----+---------+----------------+
6 rows in set (0.02 sec)
mysql> describe orders;
+-----------------+-------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+-------------------+----------------+
| customer_id | int(11) | NO | MUL | NULL | |
| order_id | int(11) | NO | PRI | NULL | auto_increment |
| order_timeStamp | timestamp | NO | | CURRENT_TIMESTAMP | |
| item | varchar(16) | NO | | NULL | |
| price | double | NO | | NULL | |
+-----------------+-------------+------+-----+-------------------+----------------+
5 rows in set (0.04 sec)
I want to get all rows of orders which match a parameterized query (my code will pass in customer_id), plus the customer name from the customers table.
How do I do that?
JOIN the two tables, and put the condition in the WHERE clause at the end of the query:
SELECT
o.order_id,
o.order_timestamp,
o.item,
o.price,
c.name,
c.address,
c.contact
FROM Orders AS o
INNER JOIN Customers AS c ON o.customer_id = c.customer_id
WHERE o.customer_id = ?
select orders.*, customers.name
from orders, customers
where orders.customer_id=customers.customer_id
and customers.customer_id='MY_ID';
Related
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');
Im still doing my SQL training. So I have two tables CUSTOMERS and ORDERS( foreign key table). Now I need to get all customers without any ORDERS. Here is my query
select LASTNAME, FIRSTNAME
from CUSTOMERS
WHERE CUSTOMERS.ID NOT IN
(select ID_CUSTOMER from ORDERS);
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| FIRSTNAME | varchar(50) | YES | | NULL | |
| LASTNAME | varchar(50) | YES | | NULL | |
| ADDRESS | varchar(100) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| PRODUCT_NAME | varchar(100) | YES | | NULL | |
| PRODUCT_PRICE | double(10,4) | YES | | NULL | |
| DATE_ORDER | date | YES | | NULL | |
| ID_CUSTOMER | int(11) | YES | | NULL | |
| AMOUNT | int(11) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
But I do recieve Empty set (0,00 sec)/ But Im sure about that those are present;
I suspect there are some NULL values in ID_CUSTOMER column of ORDERS table. NOT IN fails when there is a NULL value present in sub-query.
Use NOT EXISTS
select LASTNAME, FIRSTNAME
from CUSTOMERS C
WHERE NOT EXISTS (select ID_CUSTOMER from ORDERS O Where C.ID = O.ID_CUSTOMER );
So I'm struggling with this very (very) basic MySQL query which is supposed to retrieve courrier records ordered by number of joined reactions.
I have this table:
mysql> describe courrier;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| envoi | datetime | NO | | NULL | |
| intro | longtext | NO | | NULL | |
| courrier | longtext | NO | | NULL | |
| slug | varchar(255) | NO | | NULL | |
| categorie_id | int(11) | YES | MUL | NULL | |
| reponse | longtext | YES | | NULL | |
| recu | datetime | YES | | NULL | |
| published | tinyint(1) | NO | | NULL | |
| image_id | int(11) | YES | UNI | NULL | |
| like_count | int(11) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
12 rows in set (0.02 sec)
Which has:
mysql> select count(id) from courrier;
+-----------+
| count(id) |
+-----------+
| 56 |
+-----------+
1 row in set (0.00 sec)
Joined with:
mysql> describe reaction;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| courrier_id | int(11) | YES | MUL | NULL | |
| date | datetime | NO | | NULL | |
| ip | varchar(15) | NO | | NULL | |
| reaction | longtext | NO | | NULL | |
| url | varchar(255) | YES | | NULL | |
| name | varchar(255) | NO | | NULL | |
| status | int(11) | NO | | NULL | |
| email | varchar(255) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.01 sec)
Which has:
mysql> select count(id) from reaction;
+-----------+
| count(id) |
+-----------+
| 236 |
+-----------+
1 row in set (0.00 sec)
On: ALTER TABLE reaction ADD CONSTRAINT FK_5DA165A18BF41DC7 FOREIGN KEY (courrier_id) REFERENCES courrier (id);
(backticks removed for readability)
So when I run this query:
SELECT c0_.id AS id_0,
c0_.name AS name_1,
c0_.slug AS slug_2,
c0_.envoi AS envoi_3,
c0_.intro AS intro_4,
c0_.courrier AS courrier_5,
c0_.reponse AS reponse_6,
c0_.published AS published_7,
c0_.like_count AS like_count_8,
c0_.recu AS recu_9,
COUNT(r1_.id) AS sclr_10,
c0_.image_id AS image_id_11,
c0_.categorie_id AS categorie_id_12
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
ORDER BY sclr_10 DESC LIMIT 25
I'm quite naturally expecting to be provided with one row per record in courrier along with a additional column specifying the number of joined reaction records.
But I'm returned: 1 row in set (0.03 sec). It's the first record inserted in courrier and the additional column is filled with the number 242.
What did I do wrong?
You should use a group by clause, otherwise the count will aggregate the whole result set:
SELECT c0_.id AS id_0 /*, ...*/,
COUNT(r1_.id) AS sclr_10
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
GROUP BY c0_.id
ORDER BY sclr_10 DESC
LIMIT 25
Note: if you are also interested in courrier records that have no corresponding record in reaction (count = 0), then use LEFT JOIN instead of INNER JOIN.
I have schema like this (just experimenting, so if you have improvement suggestions I am all ears):
mysql> describe contest_entries;
+---------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+----------------+------+-----+---------+----------------+
| entry_id | int(10) | NO | PRI | NULL | auto_increment |
| member_id | int(10) | YES | | NULL | |
| person_name | varchar(10000) | NO | | NULL | |
| date | date | NO | | NULL | |
| platform | varchar(30) | YES | | NULL | |
| business_name | varchar(100) | YES | | NULL | |
| url | varchar(200) | YES | | NULL | |
| business_desc | varchar(3000) | YES | | NULL | |
| guid | varchar(50) | YES | UNI | NULL | |
+---------------+----------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
mysql> describe contest_votes;
+------------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+----------------+
| vote_id | int(10) | NO | PRI | NULL | auto_increment |
| user_id | int(10) | NO | | NULL | |
| contest_entry_id | int(10) | NO | MUL | NULL | |
| vote | int(7) | NO | | NULL | |
+------------------+---------+------+-----+---------+----------------+
And I am trying to pull the data as a leaderboard, ordering the results by the most votes. How would I do that? I am able to do the left-join part, but the sum and the ordering part of the query is confusing me.
Thank you!
SELECT entry_id
FROM contest_entries
LEFT OUTER JOIN contest_votes ON entry_id = contest_entry_id
GROUP BY entry_id
ORDER BY SUM(vote) DESC
select e.entry_id, sum(v.vote) as votes
from contest_entries e
left join contest_votes v on e.entry_id = v.contest_entry_id
group by e.member_id
order by votes desc
I have this schema:
mysql> describe suggested_solution_comments;
+-----------------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+----------------+------+-----+---------+----------------+
| comment_id | int(10) | NO | PRI | NULL | auto_increment |
| problem_id | int(10) | NO | | NULL | |
| suggested_solution_id | int(10) | NO | | NULL | |
| commenter_id | int(10) | NO | | NULL | |
| comment | varchar(10000) | YES | | NULL | |
| solution_part | int(3) | NO | | NULL | |
| date | date | NO | | NULL | |
| guid | varchar(50) | YES | UNI | NULL | |
+-----------------------+----------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
mysql> describe solution_sections;
+---------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------+----------------+
| solution_section_id | int(10) | NO | PRI | NULL | auto_increment |
| display_order | int(10) | NO | | NULL | |
| section_name | varchar(1000) | YES | | NULL | |
+---------------------+---------------+------+-----+---------+----------------+
My query is this:
select s.display_order,
s.section_name,
s.solution_section_id ,
count(c.comment_id) AS comment_count
FROM solution_sections s left outer join suggested_solution_comments c
ON (c.solution_part = s.solution_section_id)
where problem_id = 400
group by s.display_order, s.section_name, s.solution_section_id
order by display_order;
it returns only rows where there is a count > 0 but if the count is 0 it doesnt return those rows.
Any idea how to make it return all the rows? :)
Thanks!!
This is because the where problem_id = 400 removes rows with no corresponding suggested_solution_comments row. Moving the condition from the where filter to the on clause should address the problem:
select s.display_order, s.section_name, s.solution_section_id ,count(c.comment_id)
AS comment_count
from solution_sections s
left outer join suggested_solution_comments c
ON (c.solution_part = s.solution_section_id) AND problem_id = 400
group by s.display_order, s.section_name, s.solution_section_id
order by display_order;