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);
Related
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
i have queries like this
SET #curr_date = '2017-03-23';
SELECT
curr_week.mid AS MID,
curr_week.EDC AS Merchant_Name ,
COALESCE(curr_week.amount,0) AS Total_Amount_Curr_Week,
COALESCE(curr_week.total_trx,0) AS Total_Trx_Curr_Week,
COALESCE(curr_week.total_user,0) AS Total_User_Curr_Week,
COALESCE(last_week.amount,0) AS Total_Amount_Last_Week,
COALESCE(last_week.total_trx,0) AS Total_Trx_Last_Week,
COALESCE(last_week.total_user,0) AS Total_User_Last_Week
FROM
(
SELECT a.*, b.total_user
FROM
(
SELECT a1.owner_name AS MID, m.name AS EDC,SUM(t1.amount) AS amount, COUNT(t1.id) AS total_trx
FROM members m
JOIN accounts a1 ON a1.member_id = m.id
JOIN transfers t1 ON a1.id = t1.to_account_id
WHERE DATE(t1.DATE) = (#curr_date - INTERVAL 1 DAY)
GROUP BY a1.owner_name
) AS a
JOIN
(-- get total user
SELECT COUNT(r.ecash_no) AS total_user, r.mid, r.merchant_name
FROM
(
SELECT a.`owner_name` AS ecash_no,
a1.owner_name AS MID,
m.name AS merchant_name
FROM accounts a1
JOIN transfers t1 ON a1.id = t1.to_account_id
JOIN members m ON a1.member_id = m.id
JOIN accounts a ON a.id = t1.from_account_id
WHERE DATE(t1.date) = (#curr_date - INTERVAL 1 DAY)
GROUP BY a.owner_name,m.`name`
) AS r
GROUP BY r.mid
) AS b ON a.mid = b.mid
) AS curr_week
JOIN
(
-- last week
SELECT a.*, b.total_user
FROM
(
SELECT a1.owner_name AS MID, m.name AS EDC,SUM(t1.amount) AS amount, COUNT(t1.id) AS total_trx
FROM members m
JOIN accounts a1 ON a1.member_id = m.id
JOIN transfers t1 ON a1.id = t1.to_account_id
WHERE DATE(t1.DATE) = (#curr_date - INTERVAL 1 DAY) - INTERVAL 1 WEEK
GROUP BY a1.owner_name
) AS a
JOIN
(-- get total user
SELECT COUNT(r.ecash_no) AS total_user, r.mid, r.merchant_name
FROM (
SELECT a.`owner_name` AS ecash_no,
a1.owner_name AS MID,
m.name AS merchant_name
FROM accounts a1
JOIN transfers t1 ON a1.id = t1.to_account_id
JOIN members m ON a1.member_id = m.id
JOIN accounts a ON a.id = t1.from_account_id
WHERE DATE(t1.date) = (#curr_date - INTERVAL 1 DAY) - INTERVAL 1 WEEK
GROUP BY a.owner_name,m.`name`
) AS r
GROUP BY r.mid
) AS b ON a.mid = b.mid
) AS last_week ON curr_week.mid = last_week.mid
how can i retrieve all EDC value from joined queries like that.
because if i use join , it displayed only the same values.
and if i use left join, it follows the value from the left query
is there any way to display everything with join?
You can simulate a full outer join of the two tables using the following:
SELECT COALESCE(a.ColA, b.ColA) AS ColA,
COALESCE(a.ColB, b.ColB) AS ColB
FROM tableA a
LEFT JOIN tableB b ON a.ColA = b.ColA
UNION
SELECT COALESCE(a.ColA, b.ColA) AS ColA,
COALESCE(a.ColB, b.ColB) AS ColB
FROM tableA a
RIGHT JOIN tableB b ON a.ColA = b.ColA;
Note: I've assumed that only ColA is the join column. You can add ColB as a join column as well, or use only ColB as a join column. This really depends on the design of your table, but the general approach I gave should still work.
Output:
Demo here:
Rextester
I am working on a query whose purpose is to get the records of all the students whose financialyear_id!=4 and don't dispaly records even if he/she has finacialyear_id other then 4 exist.
I have written a query but it gives me the record of that student whose finacialyear_id!=4 but I want to achieve that no records will be shown if financialyear_id=4 exist for any student.
SELECT a.id aid
, s.id sid
, s.name
, s.father_name
, s.cnic
, f.financialyear_id
FROM student s
JOIN academic_info a
ON a.s_id = s.id
LEFT
JOIN fee_issued f
ON a.id = f.academic_info_id
WHERE f.financialyear_id != 4
AND a.is_data_locked = 0
AND a.university_id = 60;
Foreign Key: s_id in both tables academic_info and fee_issued,academic_info_id in fee_issued table.
You used a keyword in your request: "but I want to achieve that no records will be shown if financialyear_id=4 exist for any student." So use EXISTS (or IN which does about the same) to check for existence.
As you are using MySQL you must write the select condition for academic_info twice. Other DBMS handle this more elegantly.
select a.id as aid, s.id as sid, s.name, s.father_name, s.cnic, f.financialyear_id
from student s
join academic_info a on a.s_id = s.id and a.is_data_locked = 0 and a.university_id = 60
left join fee_issued f on f.academic_info_id = a.id
where s.id not in
(
select ai.s_id
from academic_info ai
join fee_issued fi on fi.academic_info_id = ai.id and fi.financialyear_id != 4
where ai.is_data_locked = 0 and ai.university_id = 60
);
Above query also gets you students that have no fee_issued at all. If you want these removed, change the left join to an inner join.
EDIT: Here is the same with NOT EXISTS.
select a.id as aid, s.id as sid, s.name, s.father_name, s.cnic, f.financialyear_id
from student s
join academic_info a on a.s_id = s.id and a.is_data_locked = 0 and a.university_id = 60
left join fee_issued f on f.academic_info_id = a.id
where not exists
(
select *
from academic_info ai
join fee_issued fi on fi.academic_info_id = ai.id and fi.financialyear_id != 4
where ai.is_data_locked = 0 and ai.university_id = 60
and ai.s_id = s.id
);
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
Please find the SQLfiddle URL:
http://sqlfiddle.com/#!2/c8002/1/0
Actual Output should be:
region_id status1 branches balance fses
status0 discount branch_names telecallers
2 NULL 4 400.00 30 KOTTAKKAL 341.00 3 3
2 NULL 4 800.00 31 KALPETTA 394.00 3 3
I'm getting the repeated output as follows:
region_id status1 branches balance fses
status0 discount branch_names telecallers
2 NULL 4 400.00 30 KOTTAKKAL 341.00 3 3
2 NULL 4 400.00 30 KOTTAKKAL 394.00 3 3
2 NULL 4 800.00 31 KALPETTA 341.00 3 3
2 NULL 4 800.00 31 KALPETTA 394.00 3 3
how do I correct the same?
Thanks & Regards,
Manjesh.
I guess you're having a problem in your query structure itself, as it's not simply a request for distinct.
Your joining tables, and retrieving distinct values for each row you have, that you actually wanted to be only one for each of KOTTAKKAL and KALPETTA.
Notice in your example that, although the addition of the clause distinct is performed, no difference will come over, as the rows you have are distinct. In column balance you have both 341.00 and 394.00 for each entry of KOTTAKKAL and KALPETTA.
If using group, yes, you will lose information on balance, as the result return after a group by is only the first of the different elements grouped (in case of a column with multiple values).
You either have to determine what result you want, or cope with having sum other calculation over the column balance.
I guess the result, and the proper join you were willing to do is this:
SELECT DISTINCT E.`region_id`,a0.status0,a1.status1,k.discount,k.branches
,k.branch_names, k.balance,TCLRS.telecallers,FSE.fses
FROM tbl_insurance_excel E
LEFT OUTER JOIN (SELECT E2.region_id, count(`id`) AS status1
FROM tbl_insurance_excel E2 LEFT JOIN tbl_recipt_general_details ON id=insurance_excel_id
JOIN tbl_branches ON policy_closed_branch= branch_id
WHERE E2.`row_status` =1 AND E2.canceled_status='no' AND E2.region_id=2 GROUP BY region_id) a1 ON a1.region_id=E.region_id
LEFT OUTER JOIN (SELECT E2.region_id, count(`id`) AS status0
FROM tbl_insurance_excel E2 LEFT JOIN tbl_recipt_general_details ON id=insurance_excel_id
JOIN tbl_branches ON policy_closed_branch= branch_id
WHERE E2.`row_status` =0 AND E2.canceled_status='no' AND E2.region_id=2 GROUP BY region_id) a0 ON a0.region_id=E.region_id
LEFT JOIN (
SELECT IEX.region_id, B.branch_name AS branch_names, B.branch_id AS branches, sum( DDT.discounts_amount ) AS discount, sum( RGD.`recipt_bal_amount` ) AS balance
FROM tbl_insurance_excel IEX
LEFT JOIN tbl_recipt_general_details RGD ON IEX.id = RGD.insurance_excel_id
LEFT JOIN tbl_discounts_details DDT ON RGD.rec_gene_id = DDT.recipt_general_id
LEFT JOIN tbl_branches B ON B.branch_id = RGD.policy_closed_branch
WHERE IEX.region_id =2
GROUP BY B.branch_id)k ON k.region_id=E.region_id
LEFT JOIN (
SELECT ex.region_id, B.branch_id AS branches, count( F.`fse_id` ) AS telecallers
FROM tbl_branches B
LEFT JOIN tbl_team_leader L ON B.branch_id = L.leader_branch_id
LEFT JOIN tbl_fse F ON L.leader_id = F.leader_id
JOIN (
SELECT region_id
FROM tbl_insurance_excel
WHERE `region_id` =2
GROUP BY region_id
) AS ex ON B.region_id = ex.region_id
WHERE F.fse_category = 'Telecaller'
GROUP BY B.branch_id
) TCLRS ON TCLRS .region_id=E.region_id
LEFT JOIN (
SELECT ex.region_id, B.branch_id AS branches, count( F.`fse_id` ) AS fses
FROM tbl_branches B
LEFT JOIN tbl_team_leader L ON B.branch_id = L.leader_branch_id
LEFT JOIN tbl_fse F ON L.leader_id = F.leader_id
JOIN (
SELECT region_id
FROM tbl_insurance_excel
WHERE `region_id` =2
GROUP BY region_id
) AS ex ON B.region_id = ex.region_id
WHERE F.fse_category = 'Fse'
GROUP BY B.branch_id
) FSE ON FSE.region_id=E.region_id
WHERE E.region_id=2 GROUP BY k.branches
Notice you were doing a join after the other, and combining results that should be unique in your query. You'd joined the data from the query you named k, and then joined the result with the query you named BAL, that, except by the column balance, had the same entries, and so the branch_id's were being duplicated.
You had, in a quick:
k.branch_id LEFT JOIN BAL.branch_id
which caused your rows to be duplicated, with different balance values.
The result obtained with the query posted is:
REGION_ID STATUS0 STATUS1 DISCOUNT BRANCHES BRANCH_NAMES BALANCE TELECALLERS FSES
2 (null) 4 400 30 KOTTAKKAL 341 3 3
2 (null) 4 800 31 KALPETTA 394 3 3
Regards!
Try This ::
IN your query just append the following part :
GROUP BY branch_names
OR you can get the DISTINCT in your SELECT part as :
Select DISTINCT(branch_names) from....
The final query will be ::
SELECT E.`region_id`,a0.status0,a1.status1,k.discount,k.branches
,k.branch_names,BAL.balance,TCLRS.telecallers,FSE.fses
FROM tbl_insurance_excel E
LEFT OUTER JOIN (Select E2.region_id, count(`id`) as status1
from tbl_insurance_excel E2 Left Join tbl_recipt_general_details on id=insurance_excel_id
JOIN tbl_branches on policy_closed_branch= branch_id
Where E2.`row_status` =1 AND E2.canceled_status='no' and E2.region_id=2 Group by region_id) a1 ON a1.region_id=E.region_id
LEFT OUTER JOIN (Select E2.region_id, count(`id`) as status0
from tbl_insurance_excel E2 Left Join tbl_recipt_general_details on id=insurance_excel_id
JOIN tbl_branches on policy_closed_branch= branch_id
Where E2.`row_status` =0 AND E2.canceled_status='no' and E2.region_id=2 Group by region_id) a0 ON a0.region_id=E.region_id
LEFT JOIN (
SELECT IEX.region_id,B.branch_name as branch_names,B.branch_id as branches, sum( DDT.discounts_amount ) as discount
FROM tbl_insurance_excel IEX
LEFT JOIN tbl_recipt_general_details RGD ON IEX.id = RGD.insurance_excel_id
LEFT JOIN tbl_discounts_details DDT ON RGD.rec_gene_id = DDT.recipt_general_id
LEFT JOIN tbl_branches B ON B.branch_id = RGD.policy_closed_branch
WHERE IEX.region_id =2
GROUP BY B.branch_id)k on k.region_id=E.region_id
LEFT JOIN (
SELECT IEX.region_id,B.branch_id as branches, sum( RGD.`recipt_bal_amount` ) AS balance
FROM tbl_insurance_excel IEX
LEFT JOIN tbl_recipt_general_details RGD ON IEX.id = RGD.insurance_excel_id
LEFT JOIN tbl_branches B ON B.branch_id = RGD.policy_closed_branch
WHERE IEX.region_id =2
GROUP BY B.branch_id)BAL ON BAL.region_id=E.region_id
LEFT JOIN (
SELECT ex.region_id, B.branch_id AS branches, count( F.`fse_id` ) AS telecallers
FROM tbl_branches B
LEFT JOIN tbl_team_leader L ON B.branch_id = L.leader_branch_id
LEFT JOIN tbl_fse F ON L.leader_id = F.leader_id
JOIN (
SELECT region_id
FROM tbl_insurance_excel
WHERE `region_id` =2
GROUP BY region_id
) AS ex ON B.region_id = ex.region_id
WHERE F.fse_category = 'Telecaller'
GROUP BY B.branch_id
) TCLRS ON TCLRS .region_id=E.region_id
LEFT JOIN (
SELECT ex.region_id, B.branch_id AS branches, count( F.`fse_id` ) AS fses
FROM tbl_branches B
LEFT JOIN tbl_team_leader L ON B.branch_id = L.leader_branch_id
LEFT JOIN tbl_fse F ON L.leader_id = F.leader_id
JOIN (
SELECT region_id
FROM tbl_insurance_excel
WHERE `region_id` =2
GROUP BY region_id
) AS ex ON B.region_id = ex.region_id
WHERE F.fse_category = 'Fse'
GROUP BY B.branch_id
) FSE ON FSE.region_id=E.region_id
where E.region_id=2 group by k.branches
did u try to wrap your query with another select and group it by BRANCH_NAMES
SELECT * FROM
(
<< your query goes here>>
) o
GROUP BY o.BRANCH_NAMES
But in case u put your results together like this, you will defnitely loose data in balance column.