SUM and JOIN clause in sql - sql

There are 3 tables with respective columns :
wc_dept : dept_id,dept_name
wc_doctor : dept_id,doc_id,doc_name,consult_fee
wc_patient: doc_id,consult_id,patient_name
For the following queries I am getting different results :
Query 1 :
select dept_name,sum(consult_fee)
from wc_doctor do,wc_dept dp,wc_patient p
where
do.dept_cd=dp.dept_cd
AND
do.doc_id=p.doc_id
group by dept_name;
The output for the above query is a very large amount of money for every department compared to the actual amount i.e, sum of consultation fee in each department.
Query 2 :
select dept_name,sum(consult_fee)
from wc_doctor do,wc_dept dp
where
do.dept_cd=dp.dept_cd
group by dept_name;
The output of the Query 2 gives the exact sum of consultation fee for each department.
Why is the difference between query1 and query2 ? how is consult_id column behaving in query1?

Well query1 and query2 are different.
In Second Query you are SUM how much charge each doctor in the department for check a single patient.
But in the first one you are SUM how much all the patient are pay to the department

You need to understand that the join happens before aggregation, and that joins will duplicate values in the parent table for each row in the joined child table.
consult_fee is a column in wc_doctor. You want to sum that once per row in wc_doctor. When you join to wc_patient, theconsult_fee` for each doctor is repeated, per patient, and the sum will add up over all that duplication.
If you really want to include the doctor's consult fee in a query that includes patients, you need to aggregate it separately in a subquery, then join that result against patients.

Related

SQL QUERY for sum loans per customer

enter image description here
I need a query that returns all customers whose name contains the string "Will", and their associated total loan values.
Loan totals should be sorted from largest amount to smallest amount and the loans totals column should be called "TotalLoanValue".
Only one record per customer should be returned.
SELECT name, loan_amount
FROM customers, loans
WHERE name LIKE '%WILL%'
I have wrote that query, but I'm having a hard time to figure out how to sum all the loan values per customer
To say first things first:
If you want to ask further questions here, you should please read and follow this: How to create a good example instead of just adding a link.
Otherwise, you will be on risk that your questions will just be closed and you will never get an answer.
To answer your question:
We need to JOIN the two tables by their common column and then build the SUM of all loan amounts with a GROUP BY clause of the customer name.
I didn't follow your link because I wouldn't know if this is spam, so let's say the customer table has a column "id" and the loan table a column "customer_id".
Then your query will look like this:
SELECT c.name, SUM(l.loan_amount)
FROM customers c
JOIN loan l
ON c.id = l.customer_id
WHERE c.name LIKE '%will%'
GROUP BY c.name
ORDER BY SUM(l.loan_amount) DESC, c.name;
The ORDER BY clause makes sure to begin with the customer having the highest sum of loan amounts.
The "c.name" at the end of the ORDER BY clause could be removed if we don't care about the order if different customers have the same sum of loan amounts.
Otherwise, if we use the query as shown, the result will be sorted by the sum of loan amounts first and then with a second priority by the customer name, i.e. will sort customers having the identic sum of loan amounts by their name.
Try out with some sample data here: db<>fiddle

How to find number of entries grouped by something and retrieve only those above average?

I have two tables: Profile and Record. In Profile, I have student names and other information, whereas, in Record, I have rows with curriculum information. In the Record table, a single student can have many rows. I need to calculate the number of rows grouped by student_name, but only retrieve those student names with more rows than the average (number of rows/total number of students). I can find the number of rows grouped by student_name, but I can't write a subquery to display only those above average. Could someone please explain a method to me?
This is what I have for now:
SELECT student_name, COUNT(*)
FROM Profile p
JOIN Record r
ON p._id = r._id
GROUP BY student_name
The desired output is only to retrieve students_name with the above avg no. of rows in the Records table:
student_name
No. of Records
Ali
556
John
244
Indeed you can use sub-query to get your desired output.
Code:
SELECT student, COUNT(*) AS no_of_records
FROM record
GROUP BY student
HAVING no_of_records > (SELECT COUNT(*)/COUNT(DISTINCT student) FROM record);
Explanation:
The sub-query here will return average row count from record table
In the outer-query, we are calculating number of rows for each student and comparing it with sub-query's result
Note: You can join it with profile table in outer query if needed.
Look at the fiddle to understand it better

Counting Unique IDs In a LEFT/RIGHT JOIN Query in Access

I am working on a database to track staff productivity. Two of the ways we do that is by monitoring the number of orders they fulfil and by tracking their error rate.
Each order they finish is recorded in a table. In one day they can complete many orders.
It is also possible for a single order to have multiple errors.
I am trying to create a query that provides a summary of their results. This query should have one column with "TotalOrders" and another with "TotalErrors".
I connect the two tables with a LEFT/RIGHT join since not all orders will have errors.
The problem comes when I want to total the number of orders. If someone made multiple mistakes on an order, that order gets counted multiple times; once for each error.
I want to modify my query so that when counting the number of orders it only counts records with distinct OrderID's; yet, in the same query, also count the total errors without losing any.
Is this possible?
Here is my SQL
SELECT Count(tblTickets.TicketID) AS TotalOrders,
Count(tblErrors.ErrorID) AS TotalErrors
FROM tblTickets
LEFT JOIN tblErrors ON tblTickets.TicketID = tblErrors.TicketID;
I have played around with SELECT DISTINCT and UNION but am struggling with the correct syntax in Access. Also, a lot of the examples I have seen are trying to total a single field rather than two fields in different ways.
To be clear when totalling the OrderCount field I want to only count records with DISTINCT TicketID's. When totalling the ErrorCount field I want to count ALL errors.
Ticket = Order.
Query Result: Order Count Too High
Ticket/Order Table: Total of 14 records
Error Table: You can see two errors for the same order on 8th
do a query that counts orders by staff from Orders table and a query that counts errors by staff from Errors table then join those two queries to Staff table (queries can be nested for one long SQL statement)
correlated subqueries
SELECT Staff.*,
(SELECT Count(*) FROM Orders WHERE StaffID = Staff.ID) AS CntOrders,
(SELECT Count(*) FROM Errors WHERE StaffID = Staff.ID) AS CntErrors
FROM Staff;
use DCount() domain aggregate function
Option 1 is probably the most efficient and option 3 the least.

Filtering a MariaDB SQL table for the sum of values in a column grouped by dept_name

I have an SQL table that I'm trying to write a Query for. The table has four columns, course_id, title, dept_name and credits. Every course is different and has a unique name, but many of the courses share dept_name. Each course has between 1 and 4 credits.
Complete Table
The query I'm trying to write needs to first combine the rows that have the same dept_name, and then only display the resulting departments and credit amounts with a credit sum below 30.
By using the following Query I'm able to return the credit sum grouped by dept_name, but I can't seem to only return the dept_names with a sum of less than 30. Can anyone help me out here? I've tried adding additional WHERE statements, but I just receive errors. Please let me know if this is enough or if more info is needed.
Half-Filtered Table
Use HAVING. For example:
select deptname, sum(credits)
from bk_course
group by dept_name
having sum(credits) < 30

getting duplicates when joining tables

I have two tables that I want to join. Table1 has sales order, but it doesn’t have the name of the sales person. It only has employee ID. I have table2, that has the names of employees, and employeeID is common between the two tables. Normally I would use an inner join to get the name of the sales person from table2. The problem is that on table2, there are multiple entries for each employee. If they changed manager, or changed roles within the company, or perhaps went on FMLA, it creates a new row. Therefore, when I join the tables, it creates duplicates because of the multiple entries in table2. A sale shows 3 or 4 times in my results.
Select
a.state_name
,order_number
,a.employeeID
,b.Sales_Rep_Name
,a.order_date
from
table1 as A
Inner join table2 as B
On a.employeeid = b.employeeID
where
b.monthperiod = 'November' <-- If I remove this one it adds duplicates
Is there a way to not get these duplicates? I tried distinct but didn’t work. Probably because the rows have at least one column different. I was able to eliminate the duplicates when I added a where clause asking for last month on table 2, but I am in a situation where I need all months, not just one. I have to manually change the month in order to get the full year.
Any help would be appreciated. Thanks
Use a subquery to get list of distinct employee records and then query the sales table