Database table showing multiple results per field - sql

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);

Related

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.

MS Access SQL Query merging two different fields from separate tables shows reference ID's instead of actual values

I have two separate tables in my access database, which both use a third table as the reference for one particular field on each table. The data is entered onto the different tables by separate forms. Then I have several queries that then reference those particular fields that count and show unique values. Those queries show the actual values, then I created an sql query that does the same thing, only it shows the reference ID instead of the value in the actual field.
table ODI----------table CDN----------reference table
id RHA---------id CHA----------------id HA
1 blank----------1 radio---------------1 internet
2 internet-------2 tv------------------2 radio
3 referral-------3 radio---------------3 referral
4 tv-------------4 blank---------------4 repeat customer
5 blank----------5 internet------------5 tv
6 internet-------6 referral------------6 employee
7 referral-------7 referral------------7 social media
this is the code I am trying to make work.
SELECT m.[Marketing Results], Count(*) AS [Count]
FROM (SELECT RHA as [Marketing Results] FROM ODI
UNION ALL
SELECT CHA as [Marketing Results] FROM CDN) AS m
GROUP BY m.[Marketing Results]
HAVING (((m.[Marketing Results]) Is Not Null))
ORDER BY Count(*) DESC;
and what my desired result is,
Marketing Results--Counts
referral------------------4
internet------------------3
radio---------------------2
tv------------------------2
Lookup fields with alias don't show what is actually stored in table. ID is stored, not descriptive alias. Lookup alias will carry into regular queries but Union query only pulls actual stored values. At some point need to include reference table in query by joining on key fields in order to retrieve descriptive alias. Options:
in each UNION query SELECT line, join tables
join UNION query to reference table
join aggregate query to reference table
Most experienced developers will not build lookups in table because of confusion they cause. Also, they are not portable to other database platforms. http://access.mvps.org/Access/lookupfields.htm

Retrieve count of related records

I currently have two tables in my data source that I'm referencing in this instance.
Firstly, to explain the context, I have a windows form program in VB.NET (Visual Studio 2013).
In the first table Trainer, I have the following fields : ID, First Name, Surname, Contact, Class.
In the second table Member, I have the following fields : ID, First Name, Surname, Contact, Type, TrainerID.
I have enforced referential integrity between the two tables using Trainer.ID as PK and Member.TrainerID as FK with a 1:m relationship. I'm trying to retrieve the count of related records, to the specified ID of the trainer. I want to retrieve the count of related records. So, for example on the form I click Search and provide a trainer ID, I'd like to return the amount of customers he/she has belonging to them.
I need that, so that I can work out their salary based on commission + base amount.
I've looked around a lot, read up a lot but I just can't seem to get it. Any help whatsoever will be appreciated.
If you have the trainer id, can't you just do:
select count(*) as cnt
from member m
where m.trainerid = #TheTrainerId;
select count(m.id) as count_members
from trainer t
left join member m on m.trainerid = t.id
where t.surname = 'watson'

Ms-Access: counting from 2 tables

I have two tables in a Database
and
I need to retrieve the number of staff per manager in the following format
I've been trying to adapt an answer to another question
SELECT bankNo AS "Bank Number",
COUNT (*) AS "Total Branches"
FROM BankBranch
GROUP BY bankNo
As
SELECT COUNT (*) AS StaffCount ,
Employee.Name AS Name
FROM Employee, Stafflink
GROUP BY Name
As I look at the Group BY I'm thinking I should be grouping by The ManID in the Stafflink Table.
My output with this query looks like this
So it is counting correctly but as you can see it's far off the output I need to get.
Any advice would be appreciated.
You need to join the Employee and Stafflink tables. It appears that your FROM clause should look like this:
FROM Employee INNER JOIN StaffLink ON Employee.ID = StaffLink.ManID
You have to join the Eployee table twice to get the summary of employees under manager
select count(*) as StaffCount,Manager.Name
from Employee join Stafflink on employee.Id = StaffLink.EmpId
join Employee as Manager on StaffLink.ManId = Manager.Id
Group by Manager.Name
The answers that advise you on how to join are correct, assuming that you want to learn how to use SQL in MS Access. But there is a way to accomplish the same thing using the ACCESS GUI for designing queries, and this involves a shorter learning curve than learning SQL.
The key to using the GUI when more than one table is involved is to realize that you have to define the relationships between tables in the relationship manager. Once you do that, designing the query you are after is a piece of cake, just point and click.
The tricky thing in your case is that there are two relationships between the two tables. One relationship links EmpId to ID and the other links ManId to ID.
If, however, you want to learn SQL, then this shortcut will be a digression.
If you don't specify a join between the tables, a so called Cartesian product will be built, i.e., each record from one table will be paired with every record from the other table. If you have 7 records in one table and 10 in the other you will get 70 pairs (i.e. rows) before grouping. This explains why you are getting a count of 7 per manager name.
Besides joining the tables, I would suggest you to group on the manager id instead of the manager name. The manager id is known to be unique per manager, but not the name. This then requires you to either group on the name in addition, because the name is in the select list or to apply an aggregate function on the name. Each additional grouping slows down the query; therefore I prefer the aggregate function.
SELECT
COUNT(*) AS StaffCount,
FIRST(Manager.Name) AS ManagerName
FROM
Stafflink
INNER JOIN Employee AS Manager
ON StaffLink.ManId = Manager.Id
GROUP BY
StaffLink.ManId
I don't know if it makes a performance difference, but I prefer to group on StaffLink.ManId than on Employee.Id, since StaffLink is the main table here and Employee is just used as lookup table in this query.

SQL query: HAVING, GROUP BY

I have two tables. One with a list of shops and their ID's (shop_id)
and one with a list of employees with the ID (shop_id) of the shop they work at.
I have to print out each employee with a certain position form a certain shop.
My query is normally correct but I seem to get an error like tblEmployees.
Normally my query would look something like.
SELECT tblEmployees.Name, tblEmployees.Surname, tblShops.shop_id
FROM tblEmployees, tblShops
GROUP BY tblEmployees.shop_id
HAVING tblEmployees.shop_id = tblShops.shop_id;
Normally I get an error saying something like:
tblEmployees.Name is not part of an aggregate function.
What I want to know is if it would solve my problem if I put every column that gives me this error under the GROUP BY statement. Or is there another way of fixing this error without it affecting the result I need to get from this query.
Drop the GROUP BY and HAVING clauses. You aren't aggregating here. You want to be joining your tables.
SELECT tblEmployees.Name, Surname, tblShops.shop_id
FROM tblEmployees JOIN tblShops
ON tblEmployees.shop_id=tblShops.shop_id