SQL Query: How to get data from three different tables - mysql

I am using mysql and here is the schema that I have.
First Table: Domains
+-----------+--------------------+---------------+
| domain_id | domain_name | campaign_name |
+-----------+--------------------+---------------+
| 1 | test.org | campaign 1 |
| 2 | example.org | campaign 2 |
+-----------+--------------------+---------------+
Second Table: Users
+---------+-----------------+---------------+
| user_id | first_ame | last_name |
+---------+-----------------+---------------+
| 1 | John | Zimmer |
| 2 | Brian | Roberts |
| 3 | Jon | McNeill |
| 4 | Chris | Lambert |
| 5 | Vipul | Patel |
| 6 | Logan | Green |
+---------+-----------------+---------------+
Third Table: Emails
+----------+----------------------------------+-----------+---------+
| email_id | email | domain_id | user_id |
+----------+----------------------------------+-----------+---------+
| 1 | b1#test.org | 1 | 2 |
| 2 | b2#test.org | 1 | 1 |
| 3 | a1#example.org | 2 | 2 |
| 4 | a2#example.org | 2 | 3 |
| 5 | a3#example.org | 2 | 3 |
| 6 | a4#example.org | 2 | 4 |
+----------+----------------------------------+-----------+---------+
I want to get first_name, last_name and email of specific campaign i-e campaign 2 as shown follow.
Here is Online DB Query Editor
Kindly guide me how can I write SQL query to accomplish that. Thanks

If I am not missing anything, this is basically a join. You have the ids nicely matched between the tables, so you can do:
SELECT u.*, e.email, d.campaign_name
FROM Users u JOIN
Emails e
ON u.user_id = e.user_id JOIN
Domains d
ON e.domain_id = d.domain_id
WHERE d.campaign_name = 'campaign 2';

The email table is a so called bridge table between the other two. You have to perform a join between the three tables:
SELECT first_name, last_name, email
FROM Domains JOIN Emails ON Domains.domain_id = Emails.domain_id JOIN Users ON Emails.user_id = Users.user_id
WHERE Domains.campaign_name = ...

SELECT first_name as 'First Name',last_name as 'Last Name', email as 'email ID',campaign_name as 'Compaign Name'
FROM Users u
inner join Emails e
on e.user_id = u.user_id
inner join Domains d
on d.domain_id = e.domain_id

Related

Return the data based on the statuses from other table in SQL

I have table with users:
+-----------+----------+
| id | name |
+-----------+----------+
| 1 | Joe |
| 2 | Tom |
| 3 | Jack |
| 4 | Tim |
+-----------+----------+
and second table with tasks liked with these users:
+--------------+--------------+--------------+
| id | user_id | status |
+--------------+--------------+--------------+
| 1 | 1 | new |
| 2 | 1 | done |
| 3 | 1 | in_progress |
| 4 | 2 | in_progress |
| 5 | 2 | done |
| 6 | 2 | done |
| 7 | 2 | done |
| 8 | 3 | new |
| 9 | 3 | new |
| 10 | 3 | new |
| 11 | 4 | in_progress |
| 12 | 4 | in_progress |
| 13 | 4 | new |
+--------------+--------------+--------------+
Each task could be in 'new', 'in_progress' or 'done' status.
I would like to get a list of user_ids who do not have any tasks in 'new' status but have a task in 'done' status.
Could anyone help me with this? Thanks in advance!
A variety of ways to accomplish this. Here are just a couple:
Query #1: Use CTEs
with done as (
select distinct user_id
from tasks
where status = 'done'
),
new as (
select distinct user_id
from tasks
where status = 'new'
)
select u.id, u.name
from users u
join done d
on u.id = d.user_id
where u.id not in (select user_id from new);
id
name
2
tom
Query #2: No CTEs
select id, name
from users
where id in (select user_id from tasks where status = 'done')
and id not in (select user_id from tasks where status = 'new');
id
name
2
tom
View on DB Fiddle
select u.id , u.name,t.status from users u
left join tasks t on t.user_id = u.id
where t.status<>'new';

MySQL join and concat rows without repeating entries [duplicate]

This question already has answers here:
MySQL DISTINCT on a GROUP_CONCAT()
(6 answers)
Closed 6 years ago.
I have a question about how to merge multiple row output into one row without having the same entry multiple times.
The basic setup is 4 tables:
room
appointments
users
actions
And 2 intermediate tables:
actions_appointments
users_appointments
I post the exact structure of the tables at the end of my post.
Multiple appointments can be made for one entry in the room table (n:1), but one or more users can join appointments (n:n) and one or more actions can be performed (n:n).
The problem is that I don't know how to output a single appointment with each user and action only being displayed ONCE per appointment.
With the example tables at the bottom of this post I basically want this to be my output:
|----------------|-----------|---------------------|-------------|------------------------|
| appointment_id | room_name | datetime | actions | userfullnames |
|----------------|-----------|---------------------|-------------|------------------------|
| 1 | Studio | 2016-09-01 15:30:00 | work, sleep | John Doe, Martin Smith |
| 2 | Office | 2017-04-02 13:00:00 | sleep | John Doe |
|----------------|-----------|---------------------|-------------|------------------------|
But with the queue I came up with I get this:
|----------------|-----------|---------------------|-------------|------------------------|
| appointment_id | room_name | datetime | actions | userfullnames |
|----------------|-----------|---------------------|-------------|------------------------|
| 1 | Studio | 2016-09-01 15:30:00 | work, sleep,| John Doe, Martin Smith,|
| | | | work, sleep | John Doe, Martin Smith |
| 2 | Office | 2017-04-02 13:00:00 | sleep | John Doe |
|----------------|-----------|---------------------|-------------|------------------------|
I mean I kinda get that I screwed up my joins but I'm totally stuck at the moment. Any hints? I feel like the solution is simple but I'm totally blind at the moment.
My queue:
SELECT
appointments.id AS 'appointment_id',
room.name AS 'room_name',
appointments.datetime,
GROUP_CONCAT(actions.name SEPARATOR ', ') AS 'actions',
GROUP_CONCAT(users.givenname, ' ', users.surname SEPARATOR ', ') AS 'userfullnames'
FROM appointments
INNER JOIN actions_appointments
ON appointments.id = actions_appointments.appointments_id
INNER JOIN actions
ON actions_appointments.actions_id = actions.id
INNER JOIN users_appointments
ON users_appointments.appointments_id = appointments.id
INNER JOIN users
ON users_appointments.users_id = users.id
INNER JOIN room
ON appointments.room_id = room.id
GROUP BY
appointments.id;
Table structure:
The basic tables:
|-------------------|
| room |
|-------------------|
| id | name |
|--------|----------|
| 1 | Office |
| 2 | Studio |
|-------------------|
|----------------------------------------|
| appointments |
|--------|---------|---------------------|
| id | room_id | datetime |
|--------|---------|---------------------|
| 1 | 2 | 2016-09-01 15:30:00 |
| 2 | 1 | 2017-04-02 13:00:00 |
|--------|---------|---------------------|
|-----------------------------------------|
| users |
|-----------------------------------------|
| id | username | givenname | surname |
|--------|----------|-----------|---------|
| 1 | j.doe | John | Doe |
| 2 | m.smith | Martin | Smith |
|--------|----------|-----------|---------|
|--------------------|
| actions |
|--------------------|
| id | name |
|--------|-----------|
| 1 | work |
| 2 | sleep |
|--------------------|
The intermediate tables:
|------------------------------|
| actions_appointments |
|------------------------------|
| actions_id | appointments_id |
|------------|-----------------|
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
|------------|-----------------|
|----------------------------|
| users_appointments |
|----------------------------|
| users_id | appointments_id |
|----------|-----------------|
| 1 | 1 |
| 2 | 1 |
| 1 | 2 |
|----------|-----------------|
Edit: The correct queue with DISTINCT
Thanks to Juan.Queiroz and Mike!
SELECT
appointments.id AS 'appointment_id',
room.name AS 'room_name',
appointments.datetime,
GROUP_CONCAT(DISTINCT actions.name SEPARATOR ', ') AS 'actions',
GROUP_CONCAT(DISTINCT users.givenname, ' ', users.surname SEPARATOR ', ') AS 'userfullnames'
FROM appointments
INNER JOIN actions_appointments
ON appointments.id = actions_appointments.appointments_id
INNER JOIN actions
ON actions_appointments.actions_id = actions.id
INNER JOIN users_appointments
ON users_appointments.appointments_id = appointments.id
INNER JOIN users
ON users_appointments.users_id = users.id
INNER JOIN room
ON appointments.room_id = room.id
GROUP BY
appointments.id;
GROUP BY
appointments.id,
room.name,
appointments.datetime

Join two table mysql query return all user list values?

Join two table MySQL query return all user list values.
Please correct this query or provide some query.
Table1 : users
+---------+------------+-----------+
| user_id | user_name | cource_id |
+---------+------------+-----------+
| 1 | ramalingam | 1,2,3,4 |
| 2 | yuvi | 1 |
| 3 | Saravanan | 1,2,3 |
| 4 | gandhi | 1 |
+---------+------------+-----------+
Table2 : course
+-----------+-------------+
| cource_id | cource_name |
+-----------+-------------+
| 1 | php |
| 2 | wordpress |
| 3 | seo |
| 4 | magento |
+-----------+-------------+
Output
--------------------------------------
user_id | user_name | cource_id
--------------------------------------
1 | ramalingam| php,wordpress,seo,magnto
2 | yuvi | php
3 | Saravanan | php,wordpress,seo
4 | gandhi | php
This my query
SELECT u.user_id,u.user_name, GROUP_CONCAT(c.cource_name)as course_name
FROM users as u
LEFT JOIN course as c ON c.cource_id = u.user_id
Thank you for any help I can get on this...
In general DB design is bad, don't use comma separated lists at all. Hovewer you should use FIND_IN_SET() in your JOIN clause in order to achieve this:
SELECT
u.user_id,
u.user_name,
GROUP_CONCAT(c.cource_name) AS course_name
FROM
users AS u
LEFT JOIN cource AS c ON FIND_IN_SET(c.cource_id, u.cource_id)
GROUP BY
u.user_id,
u.user_name
Output is:
+---------+------------+---------------------------+
| user_id | user_name | course_name |
+---------+------------+---------------------------+
| 1 | ramalingam | php,wordpress,seo,magento |
| 2 | yuvi | php |
| 3 | Saravanan | php,wordpress,seo |
| 4 | gandhi | php |
+---------+------------+---------------------------+
4 rows in set

MySQL, second INNER JOIN

Hi I trying to do query with couple INNER JOIN, Where is my fault?
SELECT job_tbl.id, accounts.username AS starter, accounts.username AS worker, job_tbl.comment, job_tbl.date, job_tbl.status
FROM job_tbl
INNER JOIN accounts ON job_tbl.starter = accounts.id
INNER JOIN accounts ON job_tbl.worker = accounts.id
job_tbl table here :
+----+---------+--------+---------+------+--------+
| id | starter | worker | comment | date | status |
+----+---------+--------+---------+------+--------+
| 1 | 1 | 3 | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
| 2 | 2 | 1 | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
accounts table here:
+----+------------+-----------+-------+
| id | username | extension | email |
+----+------------+-----------+-------+
| 1 | Julia | 100 | email |
+----+------------+-----------+-------+
| 2 | Eve | 101 | email |
+----+------------+-----------+-------+
| 3 | Max | 102 | email |
+----+------------+-----------+-------+
result I want it to be :
+----+---------+--------+---------+------+--------+
| id | starter | worker | comment | date | status |
+----+---------+--------+---------+------+--------+
| 1 | Julia | Max | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
| 2 | Eve | Julia | qwe | date | 10 |
+----+---------+--------+---------+------+--------+
You're not specifying which accounts table instance to use as starter or worker.
Try this:
SELECT job_tbl.id, job_tbl.description, Starter.username AS starter, Worker.username AS worker, job_tbl.comment, job_tbl.date, job_tbl.status
FROM job_tbl
INNER JOIN accounts AS Starter ON job_tbl.starter = Starter.id
INNER JOIN accounts AS Worker ON job_tbl.worker = Worker.id
The problem is you are joining two table without specifying an ALIAS on table accounts causing ambiguous state.
SELECT a.*,
b.username StarterName,
c.userName WorkerName
FROM job_tbl a
INNER JOIN account b
ON a.starter = b.id
INNER JOIN account c
ON a.worker = c.ID
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins

Get all users even if no records in another table

I'm facing a problem here :
I have two tables :
A users table :
+----+---------------+----------+
| id | username | company |
+----±---------------±----------+
| 1 | John | 0 |
| 2 | Jack | 0 |
| 3 | Casimir | 0 |
±----±---------------±----------±
A orders table :
+----+---------------+----------+--------+
| id | date | iduser | status |
+----±---------------±----------+--------+
| 1 | 2012-05-28 | 1 | 1 |
| 2 | 2012-05-25 | 1 | 1 |
| 3 | 2012-04-28 | 2 | 1 |
| 4 | 2012-03-28 | 1 | 1 |
| 5 | 2012-02-28 | 2 | 0 |
±----±---------------±----------±--------+
What I'm trying to do is to get a result like this :
+----------+---------------+-------------+
| username | COUNT(order) | MAX(date) |
+----------±---------------±-------------+
| John | 3 | 2012-05-28 |
| Jack | 1 | 2012-04-28 |
| Casimir | 0 | NULL |
±----------±---------------±-------------±
Here's the request I have for the moment :
SELECT u.username, COUNT(o.id), MAX(o.date)
FROM users u
INNER JOIN orders ON u.id = o.iduser
WHERE o.status = 1
GROUP BY u.id
This request gives me a result like :
+----------+---------------+-------------+
| username | COUNT(order) | MAX(date) |
+----------±---------------±-------------+
| John | 3 | 2012-05-28 |
| Jack | 1 | 2012-04-28 |
±----------±---------------±-------------±
As you can see, the user Casimir is not shown as he made no order. How can I modify my request to get the result I need please ?
Thanks !
A LEFT JOIN or LEFT OUTER JOIN will include all rows of the inital table, including those where there is no match in the joined-to table
SELECT u.username, COUNT(o.id), MAX(o.date)
FROM users u
LEFT OUTER JOIN orders o ON u.id = o.iduser AND o.status = 1
GROUP BY u.id
You need to use an OUTER JOIN instead of your current INNER JOIN.
Have a look at Jeff's post here to see how they differ:
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html