Tables:
cust table:
cust_id, name, etc
bill table:
bill_id, cust_id, amt, due_date, status (open/closed)
payment table:
payment_id, bill_id, amt etc
Customer can settle a single bill by paying multiple installments. So, one bill_id may relate to payment_ids.
I am unable to generate this recordset:
cust_id | due amt
'due amt' is the sum of all bill.amts - sum of all payment.amts and having status open.
Bill table
bill_id cust_id amt status
1 18 200 open
2 18 200 open
3 17 200 open
4 17 200 open
5 17 200 open
6 17 200 closed
Payment table
payment_id bill_id cust_id amt
1 1 18 50
2 2 18 40
3 3 17 10
Expected output
cust_id due_amt hint/how
17 590 (600-10) .. 600 -> because one is closed
18 310 (400-(50+40))
select c.cust_id, sum(b.amt) - sum(p.amt) as due_amt
from cust c
left join bill b on b.cust_id = c.cust_id and b.status = 'open'
left join payment p on p.bill_id = b.bill_id
group by c.cust_id
SQLFiddle demo
Related
I have 3 mysql tables:
appointments
id slot_id patient_name doctor_id deleted_at
1 11 Tasin 23 2019-10-10
2 12 Nawaz 22 null
3 13 Rakib 23 null
4 14 Hossen 23 null
5 15 Aritra 24 null
6 16 Anik 22 null
7 17 Manik 22 null
doctors
id status doctor_name
22 1 Khaled
23 1 Hasan
24 0 Rumi
slots
id date duration time
11 2019-10-10 2900 01:01
12 2019-10-11 1200 02:01
13 2019-10-18 1100 03:01
14 2019-09-08 200 11:01
15 2019-08-01 500 01:31
16 2019-10-07 300 02:31
17 2019-10-02 1200 03:31
Now, I want to show a list of doctors with their total appointment durations in decreasing order using SQL query.
Unfortunately, I don't have any idea about this SQL query. Can you assist me?
SELECT DOCTOR_NAME, SUM(DURATION) FROM APPOINTMENTS A
JOIN DOCTORS D ON D.ID = A.DOCTOR_ID
JOIN SLOTS S ON S.ID = A.SLOT_ID
GROUP BY D.ID, DOCTOR_NAME
ORDER BY SUM(DURATION) DESC;
select d.doctor_id, d.doctor_name, sum(apt.duration) as total_duration from
doctors as d
join appointments as apt on apt.doctor_id = d.doctor_id
join slots as s on s.id = apt.slot_id
group by d.doctor_id, d.doctor_name
The above query should work fine.
There might be some typo as I didn't write it in the SQL management studio.
I have two tables, customer and customer_order
Customer
cust_id, cust_name
121 Acme Wholesalers
234 Griffen Electric
336 East Coast Marine Supplies
544 Sanford Automotive
Customer_Orders
order_num,cust_id,order_date
1 121 2019-01-15
2 234 2019-07-24
3 336 2020-05-02
4 121 2019-01-15
5 336 2020-03-19
6 234 2019-07-24
7 121 2019-01-15
8 336 2020-06-12
I need to write a query that returns the name of the customer who has placed exactly 3 orders. I cannot return the same customer name than once and I must use a correlated subquery against the customer_order table.
So far I have the following, which returns all four customers.
select c.cust_name
from customer c
where exists
(select count(*)
from customer_order co
where c.cust_id = co.cust_id);
I need to add the = 3 qualifier but not sure where.
Try this:
select c.cust_name, count(co.id) as num_orders
from customer c join customer_order co on c.cust_id = co.cust_id
group by c.cust_name
having num_orders = 3;
I am assuming, that cust_name is unique, else you must group by cust_id.
I have 4 tables (1 to many):
Dont say anything about that "email" relation. It is how my developer boss built it years ago.
EMPLOYEES (+-50 results)
------------------------------------------------
id name
1 EmpName 1
2 EmpName 2
CUSTOMERS (+50k results)
------------------------------------------------
id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES (+650k results)
------------------------------------------------
id customer_email category_id
1 john#doe.com 97
2 john#doe.com 13
3 donald#duck.com 56
4 donald#duck.com 126
5 donald#duck.com 45
INTERESTS_PRODUCTS (+650k results)
------------------------------------------------
id customer_email product_id
1 john#doe.com 78
2 john#doe.com 23
3 donald#duck.com 19
4 donald#duck.com 56
5 donald#duck.com 45
So I need to filter the customers by their assigned employee and their interests.
And here is the query:
SELECT
*
FROM
(
SELECT
customers.id AS 'id',
customers.name AS 'first_name',
customers.email,
employees.id AS 'employee_id'
FROM
customers,
employees
WHERE
employees.id = 2
AND
customers.employee_assigned = employees.id
) AS myCustomers
LEFT JOIN interests_categories
ON interests_categories.customer_email = myCustomers.email
LEFT JOIN interests_products
ON interests_categories.customer_email = myCustomers.email
WHERE
(
interests_categories.category_id = 20
OR
interests_categories.category_id = 21
)
GROUP BY myCustomers.email
So, the problem:
If the employee has a low number of assigned customers (like 3) query
is successfull.
If the employee has a medium-high number of assigned customers (over 100) query stucks.
I execute SHOW PROCESSLIST and it is stucked "Generating temp table".
Anyone has idea? :(
Thank you.
Check the indexes on your tables and try this:
SELECT
c.id AS 'id',
c.name AS 'first_name',
c.email,
e.id AS 'employee_id'
ic.*,
ip.*
FROM customers c
JOIN employees e
ON c.employee_assigned = e.id
LEFT JOIN interests_categories ic
ON ic.customer_email = c.email
LEFT JOIN interests_products ip
ON ic.customer_email = c.email
WHERE
(
ic.category_id IN (20,21)
AND e.id = 2
)
GROUP BY myCustomers.email
Incidentally, a less dumb design might look like as follows. If it was me, I'd start with this, and provide properly representative CREATE and INSERT statements accordingly. Also, I'm curious about where category_id comes from - because that's potentially an area for further optimization.
EMPLOYEES
------------------------------------------------
employee_id name
6 EmpName 1
12 EmpName 2
CUSTOMERS
------------------------------------------------
customer_id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES
------------------------------------------------
customer_id category_id
1 97
1 13
2 56
2 126
2 45
INTERESTS_PRODUCTS
------------------------------------------------
customer_id product_id
1 78
1 23
2 19
2 56
2 45
I`m running this query below:
SELECT a.id as id_order, b.id as id_service,
d.nome as service_name,
c.dente as tooth,
(SELECT count(c.dente)
FROM labpedidoservicodente c
WHERE b.id = c.idLabPedidoServico) AS total,
e.valorServico as cost
FROM labpedido a
INNER JOIN labpedidoservico b
ON a.id = b.idLabPedido
INNER JOIN labpedidoservicodente c
ON a.id = c.idLabPedido
INNER JOIN labservico d
ON b.idLabServico = d.id
INNER JOIN labservicovalor e
ON b.idLabServico = e.idLabServico
WHERE a.id = '914'
My result comes this way:
order_id service_id service_name tooth total cost
914 640 SERVICE NAME 1 11 3 80.00
914 640 SERVICE NAME 1 21 3 80.00
914 640 SERVICE NAME 1 38 3 80.00
914 641 SERVICE NAME 2 11 3 84.80
914 641 SERVICE NAME 2 21 3 84.80
914 641 SERVICE NAME 2 38 3 84.80
My desired output should be like this:
order_id service_id service_name tooth total cost
914 640 SERVICE NAME 1 11-21 2 80.00
914 641 SERVICE NAME 2 38 1 84.60
The problem is that I need to concat these rows in the column "tooth" inside their respective "service_id", have tried everything but no sucess, also the total
Replace c.dente with GROUP_CONCAT(c.dente SEPARATOR ' - ') and add GROUP BY service_id below.
I have 6 tables and 3 of them is what I need to show in my table and the other 3 is what I needed to hide in the same table.
Report:
id name branch comp_id start_date end_date
100 A 001 011 2022-08-14 2022-08-14
200 B 002 012 2022-08-14 2022-08-14
Report Details:
id product_id product_code price deliveries
100 01 11 20.00 10
100 01 11 20.00 10
200 01 11 20.00 20
200 02 12 25.00 20
Products:
id code name
01 11 Prod 1
02 12 Prod 2
Product Details:
id code name Desc
01 11 Prod 1 Desc 1
02 12 Prod 2 Desc 2
Branches:
id code name
001 021 Branch 1
002 022 Branch 2
Companies:
id name branch
011 Company 1 021
012 Company 2 022
I want the output to be like this:
id: will come from reports table
branch_name: will come from branches table using the branch in report table
company_name: will come company using the comp_id in report table
product_name: will come from products table using product_id in report details table
description: will come from product_details table using product_code in report details table
start_date: will come from report table
end_date: will come from report table
id branch_name company_name product_name description start_date end_date
100 branch 1 Company 1 Prod 1 Desc 1 2022-08-14 2022-08-14
200 branch 2 Company 2 Prod 1 Desc 1 2022-08-14 2022-08-14
200 branch 2 Company 2 Prod 2 Desc 2 2022-08-14 2022-08-14
I have this sql and it all shows the id in report details table:
SELECT *, `acc`.`name` AS `cname`, `out`.`name` AS `outname`, `pro`.`name` AS `pname`, `prod`.`name` AS `sname`
FROM `report` AS `rep`
JOIN `companies` AS `acc` ON `rep`.`account_id`=`acc`.`code`
JOIN `branches` AS `out` ON `rep`.`outlet_id`=`out`.`code`
JOIN `report_details` AS `red` ON `rep`.`report_id`=`red`.`report_id`
JOIN `products` AS `pro` ON `red`.`product_id`=`pro`.`id`
JOIN `product_details` AS `prod` ON `red`.`sku_id`=`prod`.`id`
Try this:
SELECT R.id, B.name AS branch_name, C.name AS company_name, PD.product_name AS product_name, PD.Desc AS description, R.start_date
FROM Report R
LEFT JOIN report_details RD ON R.id = R.id
LEFT JOIN products P ON RD.product_id = P.id
LEFT JOIN product_details PD ON PD.product_id = PD.id
LEFT JOIN branches B ON R.branch = B.id
LEFT JOIN companies C ON R.comp_id = C.id
GROUP BY R.id, B.name, C.name, PD.product_name, PD.Desc, R.start_date