Many select statement from multiple condition - mysql

I want to display a data table with a query using many selects and various conditions, I've tried it but the result is that each column content keeps repeating and many duplicates.
I hope someone can help solve my problem
the result of my query :
While the result I want is as follows :
agent
blast
replied
responded
awaiting
no_reply
Harry
Andrian
50
20
10
10
5
James
40
20
15
6
8
Superadmin
100
20
10
10
50
I tried :
SELECT t1.agent,
t2.blast,
t3.replied,
t4.responded,
t5.awaiting,
t6.no_reply
FROM (SELECT realname AS agent
FROM user) AS t1 -- this is for agent,
(SELECT count(*) AS blast
FROM message_thread
right join user
on message_thread.agent_id = user.id
right join message
on message_thread.id = message.message_thread_id
where message.status = 'sent'
group by message_thread.agent_id) AS t2 -- this is for blast,
(select count(*) as replied
from message_thread
right join user
on message_thread.agent_id = user.id
right join message
on message_thread.id = message.message_thread_id
where message.status = 'delivered'
group by message_thread.agent_id) AS t3 -- this is for replied,
(SELECT count(DISTINCT a.id) AS responded
FROM message_thread a
right join user
on a.agent_id = user.id
WHERE
EXISTS(
SELECT 1 FROM message_thread b
right join message e
on b.id = e.message_thread_id
WHERE a.id = b.id
AND e.status = 'sent'
) and exists (
SELECT 1 FROM message_thread c
right join message f
on c.id = f.message_thread_id
WHERE a.id = c.id
AND f.status = ''
)and exists(
SELECT 1 FROM message_thread d
right join message g
on d.id = g.message_thread_id
WHERE a.id = d.id
AND g.status = 'delivered'
)
group by a.agent_id) AS t4 -- this is for responded,
(SELECT count(DISTINCT a.id) AS awaiting
FROM message_thread a
right join user
on a.agent_id = user.id
WHERE
EXISTS(
SELECT 1 FROM message_thread b
right join message e
on b.id = e.message_thread_id
WHERE a.id = b.id
AND e.status = 'sent'
)and not exists (
SELECT 1 FROM message_thread c
right join message f
on c.id = f.message_thread_id
WHERE a.id = c.id
AND f.status = ''
)and exists(
SELECT 1 FROM message_thread d
right join message g
on d.id = g.message_thread_id
WHERE a.id = d.id
AND g.status = 'delivered'
)
group by a.agent_id) AS t5 -- this is for awaiting,
(SELECT count(DISTINCT a.id) AS no_reply
FROM message_thread a
right join user
on a.agent_id = user.id
WHERE not exists(
SELECT 1 FROM message_thread d
right join message g
on d.id = g.message_thread_id
WHERE a.id = d.id
AND g.status = 'delivered'
)
group by a.agent_id) AS t6 -- this is for no_reply

Related

How do select row with max(column value) group by another column in SQL?

i dont't know how to select row with max column value group by another column. I have T-SQL
CREATE PROC GET_USER
AS
BEGIN
SELECT A.USER_ID, B.START_DATE , D.START_DATE, A.FULL_NAME,A.COST_CENTER,
F.DEPARTMENT_NAME,G.BU_NAME
FROM USERS A INNER JOIN USER_PERSON B ON A.USER_ID=B.USER_ID
INNER JOIN TYPE_PERSON C ON C.TYPE_PERSON_ID = B.TYPE_PERSON_ID
INNER JOIN USER_TRANSACTION D ON D.USER_ID = A.USER_ID
INNER JOIN TRANSACTIONS E ON E.TRANSACTION_ID = D.TRANSACTION_ID
INNER JOIN DEPARTMENT F ON F.DEPARTMENT_ID = D.DEPARTMENT_ID
INNER JOIN BUS_UNIT G ON G.BU_ID = D.BU_ID
INNER JOIN BRANCH H ON H.BRANCH_ID = D.BRANCH_ID
INNER JOIN POSITION J ON J.POSITION_ID = D.POSITION_ID
WHERE A.FLAG = 'TRUE'
END
the result will select max(B.START_DATE) and max(D.START_DATE) and Group by USER_ID
try this
SELECT T.USER_ID ,
MAX(T.START_DATE) AS [Max First Start Date] ,
MAX(T.[Second Start Date]) AS [Max Second Start Date]
FROM ( SELECT A.USER_ID ,
B.START_DATE ,
D.START_DATE AS [Second Start Date] ,
A.FULL_NAME ,
A.COST_CENTER ,
F.DEPARTMENT_NAME ,
G.BU_NAME
FROM USERS A
INNER JOIN USER_PERSON B ON A.USER_ID = B.USER_ID
INNER JOIN TYPE_PERSON C ON C.TYPE_PERSON_ID = B.TYPE_PERSON_ID
INNER JOIN USER_TRANSACTION D ON D.USER_ID = A.USER_ID
INNER JOIN TRANSACTIONS E ON E.TRANSACTION_ID = D.TRANSACTION_ID
INNER JOIN DEPARTMENT F ON F.DEPARTMENT_ID = D.DEPARTMENT_ID
INNER JOIN BUS_UNIT G ON G.BU_ID = D.BU_ID
INNER JOIN BRANCH H ON H.BRANCH_ID = D.BRANCH_ID
INNER JOIN POSITION J ON J.POSITION_ID = D.POSITION_ID
WHERE A.FLAG = 'TRUE'
) AS T
GROUP BY T.USER_ID

mysql query - count words in common between users

I've a very nice query that selects friends of the current user. user_id = 2 in the example. His friend is user_id = 4.
I want the same query to fetch the number of words user_id 2 has with selected friends. In this case they have word = love, and this is also word they both have, so I want in_common row to say = 1.
Is it possible without changing too much current query?
Should I start from scratch?
SQL FIDDLE
Assuming that both users would have an entry for 'love' in the words_en table then something like this maybe:-
SELECT b.name_surname,
b.avatar,
b.friend_words,
(b.friend_msg_id) AS friend_msg_id,
words_common.words_in_common,
COUNT(m.id) AS unread_msg
FROM
(
SELECT a.name_surname as name_surname,
a.avatar as avatar,
GROUP_CONCAT(DISTINCT w.word ORDER BY w.word ASC) AS friend_words,
(a.friend_id) AS friend_msg_id
FROM
(
SELECT f1.asked_user_id AS friend_id,
f1.created,
u.name_surname,
u.avatar
FROM friends AS f1
INNER JOIN friends AS f2
ON f1.asked_user_id = f2.asker_user_id
AND f1.asker_user_id = f2.asked_user_id
INNER JOIN users AS u ON f1.asked_user_id = u.id
WHERE f1.status = 1 AND f2.status = 1
AND f1.asker_user_id = 2
) a
LEFT JOIN connections c ON c.user_id = a.friend_id
AND c.invisible <> 1 AND c.deleted <> 1
LEFT JOIN words_en w ON c.word_id = w.id
GROUP BY 1
) b
LEFT JOIN messages m ON m.to_user_id = 2
AND m.from_user_id = b.friend_msg_id
AND m.seen = 0
LEFT OUTER JOIN
(
SELECT b.user_id AS friend_id, GROUP_CONCAT(a.word) AS words_in_common
FROM words_en a
INNER JOIN words_en b
ON a.word = b.word
WHERE a.user_id = 2
GROUP BY b.user_id
) words_common
ON b.friend_msg_id = words_common.friend_id
GROUP BY b.name_surname, b.avatar, b.friend_words, b.friend_msg_id
ORDER BY unread_msg DESC
EDIT - modification to use connections table to find common words:-
SELECT b.name_surname,
b.avatar,
b.friend_words,
(b.friend_msg_id) AS friend_msg_id,
words_common.words_in_common,
COUNT(m.id) AS unread_msg
FROM
(
SELECT a.name_surname as name_surname,
a.avatar as avatar,
GROUP_CONCAT(DISTINCT w.word ORDER BY w.word ASC) AS friend_words,
(a.friend_id) AS friend_msg_id
FROM
(
SELECT f1.asked_user_id AS friend_id,
f1.created,
u.name_surname,
u.avatar
FROM friends AS f1
INNER JOIN friends AS f2
ON f1.asked_user_id = f2.asker_user_id
AND f1.asker_user_id = f2.asked_user_id
INNER JOIN users AS u ON f1.asked_user_id = u.id
WHERE f1.status = 1 AND f2.status = 1
AND f1.asker_user_id = 2
) a
LEFT JOIN connections c ON c.user_id = a.friend_id
AND c.invisible <> 1 AND c.deleted <> 1
LEFT JOIN words_en w ON c.word_id = w.id
GROUP BY 1
) b
LEFT JOIN messages m ON m.to_user_id = 2
AND m.from_user_id = b.friend_msg_id
AND m.seen = 0
LEFT OUTER JOIN
(
SELECT b.user_id AS friend_id, GROUP_CONCAT(c.word) AS words_in_common
FROM connections a
INNER JOIN connections b
ON a.word_id = b.word_id
INNER JOIN words_en c
ON b.word_id = c.id
WHERE a.user_id = 2
GROUP BY b.user_id
) words_common
ON b.friend_msg_id = words_common.friend_id
GROUP BY b.name_surname, b.avatar, b.friend_words, b.friend_msg_id
ORDER BY unread_msg DESC

SQL JOIN vars not working

I'm trying to select variables from 3 tables using 2 left joins.
SELECT a.username, a.id, COUNT(c.featured)
FROM user a
LEFT JOIN board b
ON a.id = b.user_id
LEFT JOIN pins c
ON a.id = c.user_id
WHERE c.featured='yes'
GROUP BY b.board_name
ORDER BY COUNT(c.featured) ASC
LIMIT 3
This should get the 3 highest scoring boards from the database and arrange them according to how many times they have been featured in ascending order. I'm using this to echo:
".$info['b.board_name']."
However nothing is showing
I'm not sure if you want b.boardname or a.username, a.id in your SELECT, but you have to do the GROUP BY accordingly:
Try doing:
SELECT a.username, a.id, COUNT(c.featured)
FROM user a
LEFT JOIN board b ON a.id = b.user_id
LEFT JOIN pins c ON a.id = c.user_id
WHERE c.featured = 'yes'
GROUP BY a.username, a.id
ORDER BY COUNT(c.featured) DESC LIMIT 3
OR
SELECT b.board_name, COUNT(c.featured)
FROM user a
LEFT JOIN board b ON a.id = b.user_id
LEFT JOIN pins c ON a.id = c.user_id
WHERE c.featured = 'yes'
GROUP BY b.board_name
ORDER BY COUNT(c.featured) DESC LIMIT 3

Mysql select count on left join with condition not working

I need to count number of records on left table, i read other questions and end up with this query but the condition on COUNT is ignored
SELECT a.name, COUNT( f.status <> 'e' ) AS total
FROM album AS a LEFT JOIN photo AS f
ON a.id = f.idalbum
WHERE a.iduser = 4
GROUP BY a.id
is MySQL 5 DB
you cant specify a condition inside COUNT statment.
try this
SELECT a.name, COUNT( f.status ) AS total
FROM album AS a LEFT JOIN photo AS f
ON a.id = f.idalbum
WHERE a.iduser = 4 or f.status <> 'e'
GROUP BY a.id
What if you do:
SELECT a.name, COUNT( f.status ) AS total
FROM album AS a LEFT JOIN photo AS f
ON a.id = f.idalbum
WHERE a.iduser = 4 and f.status != 'e'
GROUP BY a.id

Performance of the SELECTs

I need some help performing my SELECTs. I made an SQL fiddle to show you the database.
I need to perform two queries but they didn't work fine:
First:
SELECT s.id, s.day_of_week, s.title
FROM slots s
LEFT JOIN bookings_has_slots bhs
ON s.id = bhs.slot_id
LEFT JOIN bookings b
ON bhs.booking_id = b.id
WHERE NOT EXISTS (
SELECT null
FROM bookings_has_slots bhs2
LEFT JOIN bookings b2
ON bhs2.booking_id = b2.id
WHERE b.date = '2018-01-27'
)
AND s.service_id = 3
AND s.day_of_week = DAYOFWEEK('2018-01-27');
Returns:
id day_of_week title
3 7 Après-midi (14h30 - 17h00)
But I expect:
no results, because the three slots possibilities for this day_of_week on the same date are taken.
Second:
SELECT DISTINCT b3.date AS unavailable_date
FROM bookings b3
LEFT JOIN bookings_has_slots bhs3
ON bhs3.booking_id = b3.id
LEFT JOIN slots s3
ON s3.id = bhs3.slot_id
WHERE NOT EXISTS (
SELECT null
FROM slots s
LEFT JOIN bookings_has_slots bhs
ON s.id = bhs.slot_id
LEFT JOIN bookings b
ON bhs.booking_id = b.id
WHERE NOT EXISTS (
SELECT null
FROM bookings_has_slots bhs2
LEFT JOIN bookings b2
ON bhs2.booking_id = b2.id
WHERE b.date = b2.date
)
AND s.service_id = 3
AND s.day_of_week = s3.day_of_week
);
Returns:
unavailable_date
2018-01-17
2018-01-31
2018-01-27
2018-02-03
But I expect:
unavailable_date
2018-01-17
2018-01-31
2018-01-27
Because here, there are two others slots available for the "2018-02-03" not taken by any other bookings.
Here is the sql fiddle :
http://sqlfiddle.com/#!9/89e46/9
Thanks for any help.
It is not the answer yet.
But Could you confirm that this will fix your 1st query:
SELECT s.id, s.day_of_week, s.title
FROM slots s
LEFT JOIN (
SELECT slot_id, booking_id
FROM bookings_has_slots bhs
INNER JOIN bookings b
ON b.id = bhs.booking_id
AND b.date = '2018-02-03'
) bhs
ON s.id = bhs.slot_id
WHERE s.day_of_week = DAYOFWEEK('2018-02-03')
AND bhs.booking_id IS NULL;
2nd query:
http://sqlfiddle.com/#!9/53a998/1
SELECT d.date unavailable_date, d.used_slots
FROM (
SELECT b.date, COUNT(b.id) used_slots
FROM bookings b
GROUP BY b.date
) d
LEFT JOIN slots s
ON s.day_of_week = DAYOFWEEK(d.date)
GROUP BY d.date
HAVING d.used_slots = COUNT(s.id);