Mysql : how i can get 3 columns from multiple tables? - mysql

I have 2 tables:
Forums:
+-----------+----------------+-----------------+-------------+---------------+
| forum_id |user_profile_id |profile_forum_id |profile_role |profile_status |
+-----------+----------------+-----------------+-------------+---------------+
| 9 | 7 | 2 | moderator | active |
| 10 | 1 | 2 | admin | active |
| 40 | 1 | 1 | admin | active |
+-----------+----------------+-----------------+-------------+---------------+
DDX:
+----+-----------+-------------+---------------+-----------------+
| id |profile_id |profile_name | DDX_content |profile_forum_id |
+----+-----------+-------------+---------------+-----------------+
| 2 | 1 | user1 | 874420 | 1 |
| 3 | 1 | user2 | 124500 | 2 |
+----+-----------+-------------+---------------+-----------------+
Now i want to get list of all users(with 3 columns: profile_name, DDX_content, profile_role) that have 'admin' or 'moderator' role for specific forum id. How i can do that?

Try this request :
SELECT
d.profile_name,
d.DDD_content,
f.profile_role
FROM
DDX AS d
INNER JOIN
Forums AS f
ON f.profile_forum_id = d.profile_forum_id
WHERE
(profile_role = 'admin' OR profile_role = 'moderator')
AND forum_id = 9;

select ddx.profile_name, ddx.DDX_content, f.profile_role
from ddx
join forums f on f.user_profile_id = ddx.profile_id
where profile_role in ('admin','moderator')
and forum_id = 123

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

How can I determine which user is the top one in the specific tag?

I have a question and answer website like stackoverflow. Here is the structure of some tables:
-- {superfluous} means some other columns which are not related to this question
// q&a
+----+-----------------+--------------------------+------+-----------+-----------+
| id | title | body | type | related | author_id |
+----+-----------------+--------------------------+------+-----------+-----------+
| 1 | How can I ... | I'm trying to make ... | q | NULL | 3 |
| 2 | | You can do that by ... | a | 1 | 1 |
| 3 | Why should I .. | I'm wonder, why ... | q | NULL | 1 |
| 4 | | First of all you ... | a | 1 | 2 |
| 5 | | Because that thing ... | a | 3 | 2 |
+----+-----------------+--------------------------+------+-----------+-----------+
// users
+----+--------+-----------------+
| id | name | {superfluous} |
+----+--------+-----------------+
| 1 | Jack | |
| 2 | Peter | |
| 3 | John | |
+----+--------+-----------------+
// votes
+----+----------+-----------+-------+-----------------+
| id | user_id | post_id | value | {superfluous} |
+----+----------+-----------+-------+-----------------+
| 1 | 3 | 4 | 1 | |
| 2 | 1 | 1 | -1 | |
| 3 | 2 | 1 | 1 | |
| 4 | 3 | 2 | -1 | |
| 5 | 1 | 4 | 1 | |
| 6 | 3 | 5 | -1 | |
+----+--------+-------------+-------+-----------------+
// tags
+----+------------+-----------------+
| id | name | {superfluous} |
+----+------------+-----------------+
| 1 | PHP | |
| 2 | SQL | |
| 3 | MySQL | |
| 4 | HTML | |
| 5 | CSS | |
| 6 | C# | |
+----+------------+-----------------+
// q&aTag
+-------+--------+
| q&aid | tag_id |
+-------+--------+
| 1 | 1 |
| 1 | 4 |
| 3 | 5 |
| 3 | 4 |
| 4 | 6 |
+-------+--------+
Now I need to find top users in a specific tag. For example, I need to find Peter as top user in PHP tag. Because his answer for question1 (which has PHP tag) has earned 2 upvotes. Is doing that possible?
Try this:
select q1.title, u.id, u.name, sum(v.value) total from `q&a` q1
left join `q&atag` qt ON q1.id = qt.`q&aid`
inner join tags t ON qt.tag_id = t.id
left join `q&a` q2 ON q2.related = q1.id
left join users u ON q2.author_id = u.id
left join votes v ON v.post_id = q2.id
where t.name = 'PHP'
group by q1.id, u.id
and here is a simple divided solution:
Let us divide it into sub queries:
get the id of the tag you will search for: select id from tags where name = 'PHP'
get the questions with this tag: select 'q&aid' from 'q&aTag' where tag_id = 1.
get the ids of answers for that question: select id, author_id fromq&awhere related in (2.)
get the final query: select user_id, sum(value) from votes where post_id in (3.) group by user_id
Now combining them all give the result:
select user_id, sum(`value`) total from votes
where post_id in (
select id from `q&a` where related in (
select `q&aid` from `q&aTag` where tag_id IN (
select id from tags where name = 'PHP'
)
)
)
group by user_id
you can add this at the end if you want only one record:
order by total desc limit 1

MySql Left Join with subselect

I have 2 tables (user and infos).
I need to select all user data and the related last inserted 'infotext' (insert_time)
table user
+----+--------+----------+
| id | name | adress |
+----+--------+----------+
| 1 | Name 1 | Adress 1 |
| 2 | Name 2 | Adress 2 |
| 3 | user 3 | adress 3 |
| 4 | user 4 | adress 4 |
+----+--------+----------+
table infos
+----+---------+----------+---------------------+
| id | id_user | infotext | insert_time |
+----+---------+----------+---------------------+
| 1 | 1 | info 1 | 2016-11-24 14:03:23 |
| 2 | 1 | info 2. | 2016-11-24 14:08:30 |
| 3 | 3 | text 3. | 2016-11-24 14:08:46 |
+----+---------+----------+---------------------+
My current query is:
SELECT a.*, b.infotext FROM user a LEFT JOIN infos b
ON a.id = b.id_user
LEFT JOIN
(
SELECT id_user, MAX(insert_time) newestInsert
FROM infos
GROUP BY id_user
) c ON c.id_user = b.id_user AND
c.newestInsert = b.insert_time
But the problem is it outputs the id not distinct:
+----+--------+----------+----------+
| id | name | adress | infotext |
+----+--------+----------+----------+
| 1 | Name 1 | Adress 1 | info 1 |
| 1 | Name 1 | Adress 1 | info 2. |
| 3 | user 3 | adress 3 | text 3. |
| 2 | Name 2 | Adress 2 | NULL |
| 4 | user 4 | adress 4 | NULL |
+----+--------+----------+----------+
The final result I need is:
+----+--------+----------+----------+
| id | name | adress | infotext |
+----+--------+----------+----------+
| 1 | Name 1 | Adress 1 | info 2. |
| 3 | user 3 | adress 3 | text 3. |
| 2 | Name 2 | Adress 2 | NULL |
| 4 | user 4 | adress 4 | NULL |
+----+--------+----------+----------+
Put the second condition in the on clause. This method does it as a correlated subquery:
SELECT u.*, i.infotext
FROM user u LEFT JOIN
infos i
ON u.id = i.id_user and
i.insert_time = (SELECT MAX(i2.insert_time)
FROM infos i2
WHERE i2.id_user = i.id_user
);
If performance is key...
SELECT u.id
, u.name
, u.adress
, i.infotext
FROM user u
LEFT
JOIN
( SELECT x.*
FROM infos x
JOIN
( SELECT id_user
, MAX(insert_time) insert_time
FROM infos
GROUP
BY id_user
) y
ON y.id_user = x.id_user
AND y.insert_time = x.insert_time
) i
ON i.id_user = u.id
ORDER
BY infotext IS NULL, infotext;

sql select query from two different tables WHERE active=1

i try select all columns from two different tables WHERE active = 1
i have 2 tables table_pro and table_basic,
sql:"select * from table_basic,table.name";
and 2 condition:
WHERE active = 1
WHERE table_pro.id = table_basic.name.id
how to make it correctly
Here is table_pro
+----+--------+---------+-----------+
| id | people | rooms | active |
+----+--------+---------+-----------+
| 1 | 5 | 10 | 0 |
| 2 | 12 | 17 | 0 |
| 3 | 21 | 38 | 1 |
+----+--------+---------+-----------+
Here is table_basic
+---------+-------+---------+------------+----------+
| name_id | name | balance | title | time |
+---------+-------+---------+------------+----------+
| 1 |shop | 100 | failed | 15:10:20 |
| 2 |factory| 75 | error | 15:10:20 |
| 3 |studio | 25 | timed_out | 15:10:20 |
+---------+-------+---------+------------+----------+
I'd like to have this output result only rows (from of all columns) with status active = 1
+-----+-------+----- --+--------+-------+----------+---------+--------+
| id | people| rooms | name |balance| title | time | active |
+-----+-------+--------+--------+-------+----------+---------+--------+
| 3 | 21 | 38 | studio |25 | timed_out| 15:10:20| 1 |
+-----+-------+--------+--------+-------+----------+---------+--------+
Thanks
SELECT A.id, A.people, A.rooms, B.name, B.balance, B.title, B.time, A.active
FROM
table_pro AS A
JOIN
table_basic AS B
ON
A.id = B.name_id
WHERE
A.id = 3
SELECT table_pro.*, table_basic.*
FROM table_pro
INNER JOIN table_basic
ON table_basic.name_id = table_pro.id
WHERE table_pro.active = 1

MySQL - Get rows with same value

I have two tables for an app with a conversation feature. It has a sessions table which holds conversation sessions and a session participants table that holds the participants for a conversation. Now, I want to get all the other participants that I have a conversation with.
`sessions` table
+----+---------+
| id | session |
+----+---------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+---------+
`session_participants` table
+----+---------+------+
| id | session | user |
+----+---------+------+
| 1 | A | 1 |
| 2 | A | 2 |
| 3 | B | 3 |
| 4 | B | 2 |
| 5 | C | 1 |
| 6 | C | 4 |
+----+---------+------+
Let say my id is 1, how can I get users with the id 2 & 4 which I have a conversation with in the sessions A & C?
Thank you for your responses.
SELECT sp2.user
FROM session_participants AS sp1
JOIN session_participants AS sp2 ON sp2.session = sp1.session AND sp2.id != sp1.id
WHERE sp1.user = 1