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

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.

Related

SQL Query - select multiple rows from 2 tables

I'm new to SQL and recently saw this question, which is described on the [attached picture]
. Any suggestions on how to solve it? Thanks in advance.
In most cases such requirements are better to resolve by starting from the end. Let's try that: "have more than 3 items ... and total price".
select InvoiceId, sum(price)
from InvoiceItem
group by InvoiceId
having count(1) > 3;
This query gives you the overall price for every invoice that has more than 3 items. You might be wondering why there is that funny "having" clause and not the "where" clause.
The database executes first "from" and "where" parts of the query to get the data and only after that using aggregations (sum, count etc.) is possible, so they are to be specified afterwards.
The query above actually returns all the data from requirement, but I assume that whoever gave you this task (that was a teacher, right?) was asking you to retrieve all the data from Invoices table that correspond to the records within the InvoiceItem table that has more than 3 items and so on.
So, for now all you have left is to join the Invoice table with a query from above
select i.id, i.customername, i.issuedate, sum(it.price)
from InvoiceItem it
join Invoice i on it.invoiceid = i.id
group by i.id, i.customername, i.issuedate
having count(1) > 3;
Teacher might ask you why did you use count(1) and not count(*) or count(id) or something. Just tell him/her all these things are equal so you picked just one.
Now it should be working fine presumably. I did not tested it at all as you did not provide the data to test it on and it is late so I am pretty tired. Because of this you might needed to fix some typos or syntax errors I probably made - but hey let's keep in mind you still have to do something on your own with this task.

duplicated rows in select query

I am trying to run a query to get all the customers from my database. These are my tables in a diagram :
when running the query by joining the table Companies_Customers and the Customers table based on the customerId in both tables(doesn't show in the join table in the pic), I get duplicate rows, which is not the desired outcome.
This is normal from a database standpoint since a Customer can be related to different companies (Companies can share single customer).
My question is how do I get rid of the duplication via SQL.
There can be 2 approaches to your problem.
Either only select data from Customers table:
SELECT * FROM Customers
Or select from both tables joined together, but without CompanyName and with GROUP BY CompanyCustomerId - although I highly suggest the first approach.

Select distinct record with join count records

I have two tables: Company and Contact, with a relationship of one-to-many.
I have another table Track which identifies some of the companies as parent companies to other companies.
I want to write a SQL query that selects the parent companies from Track and the amount of contacts that each parent has.
SELECT Track.ParentId, Count(Contact.companyId)
FROM Track
INNER JOIN Contact
ON Track.ParentId = Contact.companyId
GROUP BY Track.ParentId
however The result holds less records than when I run the following query:
SELECT DISTINCT Track.ParentId
FROM Track
I tried the first query with an added DISTINCT and it returned the same results (less then what it was meant to).
You're performing an INNER JOIN with the Contact table, which means that any rows from the first table (Track in this case) with no matches to the JOINed table will not show up in your results. Try using a LEFT OUTER JOIN instead.
The COUNT with Contact.companyId will only count rows where there is a match (Contact.companyId is not NULL). Since you're counting contacts that's fine as they will count as 0. If you were trying to count some other set of data and tried to do a COUNT on a specific column (rather than COUNT(*)) then any NULL values in that column would not count towards your total, which might or might not be what you want.
I used an INNER JOIN which returns only records that are identical in both tables.
To return all records from Track table, and records that match in the Contact table, I need to use LEFT JOIN.

how can an unrelated table specified in FROM-clause affect the outcome of SUM()?

I am new to sqlite3 and have made some queries where the outcome seems strange to me. I have two tables, OrderDetails and Offices, that from their schema are unrelated. There are 7 entries in offices and 2996 in OrderDetails. Within OrderDetails, there is a column with quantityOrdered, and by summing the column values I get an accumulated value.
SELECT SUM(quantityOrdered) FROM OrderDetails; (result is 105516)
When I include the other table, which i don't actually extract any information from in my SELECT-clause and should be unrelated in attributes like so:
SELECT SUM(OD.quantityOrdered FROM OrderDetails OD, Offices; (result is 738612)
The result is much higher, and it is interesting to see that it is exactly 7 times larger (the number of entries in offices). I also get it even though I specify that it should only be OrderDetails attributes (OD.quantityOrdered). Is there some obvious logic that I don't see and understand? I hope someone can help me.
You are getting the sum for a CROSS JOIN since you dont have a JOIN condition.
Every row FROM the first table is JOINed to every other row from the other table.
Look here for a basic JOIN tutorial.
It should be
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails OD JOIN Offices O
ON OD.somecol=O.someothercol
When you list two tables in a FROM clause but specify no conditions to relate them together, you get what is known as a CROSS JOIN, which calculates every possible combination of rows from the two tables.
You can see this by running
SELECT *
FROM OrderDetails, Offices
In more modern SQL that would be written
SELECT *
FROM OrderDetails
CROSS JOIN Offices
The SUM() function (without a GROUP BY) runs across all the rows in the result set, regardless of how the resultset was calculated (you can think of the SELECT clause running after the CROSS JOIN).
So your second query takes all the rows created by the CROSS JOIN and sums them up, meaning all the values are counted 7 times.
SELECT SUM(OD.quantityOrdered)
FROM OrderDetails as OD
CROSS JOIN Offices as O

Database table showing multiple results per field

Attempting to form a query using 2 tables involving member of a cycling club and their respective place in a race with Microsoft Access. When I attempt to run the following SQL code I get a query table that displays every RaceID and Member, but doesn't link each member to 1 place per race.
SELECT RaceID, LastName, FirstName, Place
FROM Members, RaceResults;
What I do wind up with is a listing for every member of the club in all places (1-10) in every race. I have attempted to do both a count function per raceID and a Join function to combine the memberID's between both tables. Neither seem to either work, or have the same result as my current table. I would appreciate any suggestions on what I am missing in my SQL Query to properly display my table.
When you join the result of 2 tables, you need to tell the database how they are linked, otherwise you'll get a cartesian product of both tables,.
Example:
SELECT t.RaceID, t.LastName, t.FirstName, tt.Place
FROM Members t join RaceResults tt on (t.RaceId = tt.RaceId);