Combining two SQL queries in Access - sql

I've been trying for a couple of hours or so this morning to combine two access (Access 365) queries into one statement so I can run a report off of it. I've read around the forums and have tried various combinations but cannot get them to work. I'm not an SQL guru and was wondering if someone can help and point out where I'm going wrong.
I have a table (data) it has 2 relevant columns
Audit username, Attendance Ref Name,
each time an order is created it gets logged,
if it was electronic the user name is "DRIP" if manually entered it gets the logged in user name.
What I would like is one row for each requester with Column one being the requester name (Attendance Ref Name), Column 2 being number of times the requester appears (Total Number of requests), Column 3 total number of times the requester has made it electronically (Total Number of Electronic requests)
so I can produce a 4th column so show me percentages of electronic requests by the requester
What I have working is two queries
WORKING STATMENTS (written in Notepad - I'm omitting the -- line in access):
--Total number of unique requests per requester
SELECT DISTINCT Data.[Attendance Ref Name], Count(Data.[Attendance Ref Name]) AS [Total Number of requests]
FROM Data
GROUP BY Data.[Attendance Ref Name]
and
--Total Number of unique requester received electronically per Requester.
SELECT DISTINCT Data.[Attendance Ref Name], Count(Data.[Attendance Ref Name]) AS [Total Number of Electronic requests]FROM Data WHERE (((Data.[Audit Username])="DRIP"))
GROUP BY Data.[Attendance Ref Name];
WHAT I have tried:
SELECT DISTINCT Data.[Attendance Ref Doctor Name], Count(Data.[Attendance Ref Doctor Name]) AS [Total Number of requests]FROM Data
UNION
SELECT DISTINCT Data.[Attendance Ref Doctor Name], Count(Data.[Attendance Ref Doctor Name]) AS [Total Number of Electronic requests]FROM Data WHERE (((Data.[Audit Username])="DRIP"))
GROUP BY Data.[Attendance Ref Doctor Name];
and
SELECT
(SELECT DISTINCT Data.[Attendance Ref Doctor Name], Count(Data.[Attendance Ref Doctor Name])FROM Data) AS [Total Number of requests],
(SELECT DISTINCT Data.[Attendance Ref Doctor Name], Count(Data.[Attendance Ref Doctor Name])FROM Data WHERE Data.[Audit Username]="DRIP")AS [Total Number of Electronic requests]
I have even been through https://www.w3schools.com/sql/default.asp tutorials
but I cannot get them working anyone able to help please and put me out of my misery?
thanks in advance for any help

You need to use a join to link the result from your first and second query together.
Assuming all ref names are in both tables, you can use the following:
SELECT q1.[Attendance Ref Name], q1.[Total Number of requests], q2.[Total Number of Electronic requests]
FROM (
SELECT DISTINCT Data.[Attendance Ref Name], Count(Data.[Attendance Ref Name]) AS [Total Number of requests]
FROM Data
GROUP BY Data.[Attendance Ref Name]
) AS q1
INNER JOIN (
SELECT DISTINCT Data.[Attendance Ref Name], Count(Data.[Attendance Ref Name]) AS [Total Number of Electronic requests]FROM Data WHERE (((Data.[Audit Username])="DRIP"))
GROUP BY Data.[Attendance Ref Name]
) AS q2
ON q1.[Attendance Ref Name] = q2.[Attendance Ref Name]

Related

Selecting additional data/values to display as column in query or in form

I have an employee index, that I need to run queries on for each employee, and display that output along with the original employee.
So say the employee index has an ID, batch, status, and multiple other columns. I have a table where I keep track of every time a column in the employee index changes. I want to display and later export dates of when certain columns use to equal other values, right along side the original employee row.
Naturally I tried creating a form to display multiple value, added a text box to hold my extra information, and changed the value of the text box for each Form_Current event in VBA.
Private Sub Form_Current()
Me.txtPhaseOne = SimpleLookup("SELECT TOP 1 ChangeDate FROM EmployeeVariables WHERE VariableName = ""Batch"" AND EmployeeID = " & Me.Recordset("ID Number") & " ORDER BY ChangeDate ASC", "ChangeDate")
End Sub
It seemed to work at first...
Until I realized the dates were set to whatever the current record date should be
[
So then I tried a join:
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
EVA.ChangeDate as Phase1
FROM
EmployeeIndex
(SELECT TOP 1 ChangeDate FROM EmployeeVariables WHERE EmployeeID = EmployeeIndex.[ID Number] ORDER BY CHangeDate) EVA
Which would work, if I could some how prefetch EmployeeIndex.[ID Number]. (I didn't name these columns) Except I haven't got the slightest clue and I'm running on fumes.
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
EVA.ChangeDate as Phase1
FROM
EmployeeIndex
INNER JOIN
(SELECT TOP 1 EmployeeID, ChangeDate FROM EmployeeVariables WHERE ORDER BY ChangeDate) EVA
ON EmployeeIndex.[ID Number] = EVA.EmployeeID
Try with a subquery:
SELECT
EmployeeIndex.[ID Number],
EmployeeIndex.Batch,
EmployeeIndex.Status,
EmployeeIndex.[First name],
EmployeeIndex.[Last name],
(SELECT Max(EVA.ChangeDate)
FROM EmployeeVariables AS EVA
WHERE EVA.EmployeeID = EmployeeIndex.[ID Number]) AS Phase1
FROM
EmployeeIndex
Cross Apply will be perfect for your TOP 1 case, as it will run for each employeeID rather than just joining on 1

is there a working option that can pick lowest number(s) for my case?

I am currently having problem with picking lowest percent score (or scores if there are similar ones) and lay it out with 5 columns. The two options I tried to give me errors and I'm not sure if my layout is just wrong or i need to group them differently!
So far I've tried picking a lowest number by just using "min" which still listed all of the percent scores (instead of picking lowest) and using "asc" option which gave me an error.
One option:
select name, minor, [Course Name], [Courses Taken t].Department, [percent score] , GPA
from [Student Information t], [Courses Taken t], [Courses t]
where name like 'Insert Name'
and [Student Information t].studentID=[Courses Taken t].studentID
and [Student Information t].Minor is not null
group by [Percent Score] order [Percent Score] ASC limit 1
Result:
Error: Msg 102, Level 15, State 1, Line 6
Incorrect syntax near 'Percent Score'.
Another Option:
select name, minor, [Course Name], [Courses Taken t].Department, min([percent score]) as [percent score], GPA
from [Student Information t], [Courses Taken t], [Courses t]
where name like 'Insert Name'
and [Student Information t].studentID=[Courses Taken t].studentID
and [Student Information t].Minor is not null
group by name, minor, [Course Name], [Courses Taken t].Department, GPA
Result: listed all percent scores (instead of the lowest)
I want results to give me the lowest number. In this case, there are two numbers that are the same so I would like them both listed, but I am not sure what I am doing wrong! Any hints would be appreciated <3
My guess is the query you want is this, however, it has a few comments in it:
SELECT TOP 1
SI.[name], --Guessed table
SI.minor, --Guessed table
CT.Department,
C.[percent score], --Guessed table
C.GPA --Guessed tables
FROM [Student Information t] SI
JOIN [Courses Taken t] CT ON SI.studentID = CT.studentID
CROSS JOIN [Courses t] C --Should this be a CROSS JOIN? You had no implicit JOIN in your WHERE
WHERE SI.[name] = 'Insert Name'
--Removed GROUP BY, this query has no aggregation
ORDER BY C.[percent score]; --ORDER BY, not ORDER
This is basically how you should have written your first query. Hopefully, even if this doesn't give you the result set you're after, it gets you close enough.

MS Access: First () function in query not retrieving correct values

I have 4-6 tables, but the main ones are LRTTable and TempTable. They are joined using INNER JOIN and result set is LEFT JOIN with other 6 tables.
LRTable and Temp Table contains Store ID ,PCC Id ,COF NO, Line of Business Name, Status, Address and few other columns. LRTable can have duplicate records for same Store ID with different COF No(0,7987987) and Line of Business Name(Food and Retail).
Temp Table has Store ID, PCC. Combination of these two are primary key in Access.
Query is correctly able to pull all the data from LRTable based on TempTable. For example, query pulls all the records (including duplicates)from LRtable when there is match in Temp Table and are sorted based on status code and line of business. By doing so I am ensuring the active and food records are available on the top.
What I need to achieve is, instead of having multiple records for each store in the query result set, I want only top record from set of records of each store from the result set. I am able to this with the first function, however its picking values fron LRTable rather than sub query result
Is there a way I can just pick from sub query ?
LRTable:
Store ID PCC ID Status Line of Business Name COF No
---------- -------- ---------- -----------------------
1 123 Active Food 999
1 123 InActive Food 89899
1 123 Active Retail 0
2 222 Active Retail 0
2 222 InActive food 76767
TempTable
Store ID : 1 and 2
PCC : 123 and 222
Result:
- 1,0
- 2,0
Expected output:
- 1,999
- 2,76767
Below is the query with first
SELECT StoreID,FIRST (COF No) from
(
select * from
(
SELECT distinct TempTable.[Avendra ID],
TempTable.[Marsha Code],
LRTable.[Concept Name],
LRTable.[Outlet (Store) Name],
LRTable.[Outlet Street Address Text ID],
LRTable.[Outlet City ID],
LRTable.[Outlet State ID],
LRTable.[Outlet Zip Code ID],
LRTable.[Status Code ID],
LRTable.[Outlet SAP ID ID],
LRTable.[Outlet PCC ID ID],
LRTable.[COF Number ID],
CLPSource.[Brand Mandated],
FROM (
(
(
(
(
(
LRTable INNER JOIN TempTable
ON LRTable.[Outlet PCC ID ID] = TempTable.[PCC ID]
AND LRTable.[Store Number ID] = TempTable.[Store Number ID]
) LEFT JOIN CLPSource
ON TempTable.[Avendra ID] = CLPSource.[Avendra Customer ID]
) LEFT JOIN OasisReportSource
ON TempTable.[Marsha Code] = OasisReportSource.[Marsha])
ORDER BY LRTable.[Status Code ID],
LRTable.[Line of Business Name]))
Group by LRTable.[StoreID]
Using the data, actual output and desired output you provide in your LRTemp table and Temp Table panels, I reckon can be done using the FIRST aggregate function i.e.
SELECT StoreID, FIRST(PCC ID), FIRST(Status), FIRST(Line of Business Name), FIRST (COF No)
FROM (joined LRTable and TempTable)
GROUP BY StoreId
You should then get the data of first-occurring record for each StoreId.

LOOP and COUNT in a SELECT statement SQL SERVER

I have a view with these columns
and i want to extract this data
i am doing it in SQL Server manually in several steps and i want to automate it so that i can run a select statement directly from a macro and save it in excel file.
Here is what i am doing
select distinct
CASE
WHEN Userid ='jsolar' THEN 'Jack Solar'
WHEN Userid ='jkrcmarikova' THEN 'Jana Krcmarikova'
WHEN Userid ='lfialova' THEN 'lucia fialova'
WHEN Userid ='zsnopkova' THEN 'zuzana snopkova'
END AS [User Name]
, Region
from [SC].[vw_X86_Orders_By_UserID_GAMMA]
order by Region, [User Name]
Then i copy the result in excel file and run other queries for each user
SELECT Count ( DISTINCT [Order Number])
FROM [SC].[vw_X86_Orders_By_UserID_GAMMA]
where Userid LIKE 'jsolar'
AND Region LIKE 'CENTRAL'
and [Order Entry Date] = '2016-10-27'
i save this result in number of distinct order number. Then i run this query
SELECT Count ( DISTINCT CONCAT ([Order Number], [Line No]))
FROM [SC].[vw_X86_Orders_By_UserID_GAMMA]
where Userid LIKE 'jsolar'
AND Region LIKE 'CENTRAL'
and [Order Entry Date] = '2016-10-27'
I save this result in number of distinct order number concatenated with line no. And i repeat the same for each user
At the end it should be something like this in Excel
Is there a way how to do this in one select statement to loop each user and count for all users at the same time ? Thank you very much.
I really don't think you need a "LOOP". SQL operates best in set based operations returning recordsets with many rows. So we need to treat [SC].[vw_X86_Orders_By_UserID_GAMMA] as an entire set and simply update the case statement to translate all users names (assuming you have to have them, or you could do a vlookup on the userID in excel after the fact)
I think what you're really after is the count(distinct column) in combination with a group by on userID and region.
Based on comments I think you would need to amend the case statements in the select and group by to contain the translation for all the users.
I think there's too many unknowns to provide a 100% correct response but here's a shot across the bow..
SELECT CASE WHEN Userid ='jsolar' THEN 'Jack Solar'
WHEN Userid ='jkrcmarikova' THEN 'Jana Krcmarikova'
WHEN Userid ='******' THEN '**** *******'
WHEN Userid ='****' THEN '***** ****' END AS [User Name]
, Region
, count(distinct [Order Number]) as cntDistinctOrders
, count(Distinct concat([order Number], [Line No]) as cntDistinctOrderLines
FROM [SC].[vw_X86_Orders_By_UserID_GAMMA]
WHERE [Order Entry Date] = '2016-10-27'
-- and Region = 'CENTRAL' don't think you need this the group by handles same names in different regions keeping them distinct and counts seperate.
GROUP BY CASE WHEN Userid ='jsolar' THEN 'Jack Solar'
WHEN Userid ='jkrcmarikova' THEN 'Jana Krcmarikova'
WHEN Userid ='******' THEN '**** *******'
WHEN Userid ='****' THEN '***** ****'
END
, Region
ORDER BY [User Name], Region
To put this in plain English...
You want all the usernames and regions for each user in the [SC].[vw_X86_Orders_By_UserID_GAMMA] schema.table showing the distinct count of orders and order lines for a specific date.
If you can use a Vlookup in excel for the names you could getaway without the case statements and all that extra code..
SELECT UserId [User Name]
, Region
, count(distinct [Order Number]) as cntDistinctOrders
, count(Distinct concat([order Number], [Line No]) as cntDistinctOrderLines
FROM [SC].[vw_X86_Orders_By_UserID_GAMMA]
WHERE [Order Entry Date] = '2016-10-27'
-- and Region = 'CENTRAL' don't think you need this the group by handles same names in different regions keeping them distinct and counts seperate.
GROUP BY CASE UserID
, Region
ORDER BY [User Name], Region
--note because the group by executes before the select statement, we have to group by the USERID and not the alias name of [User name]

Have blank fields in query on purpose

I have a Microsoft Access database with the following table:
TableName: Parts
Cabinet ID - Number
Part ID - Number
PartClass - Number
Width - Number (double)
Length - Number (double)
Description - Text
I use the following SQL queries to get three views:
DoorPanels:
SELECT Parts.[Cabinet ID], Count(Parts.[Cabinet ID]) as Qty, Parts.Description as Name Parts.Width, Parts.Length
FROM Parts
WHERE PartClass=13 GROUP BY Parts.[Cabinet ID], Parts.Description, Parts.Width, Parts.Length
ORDER BY Parts.[Cabinet ID]
DoorRails:
SELECT Parts.[Cabinet ID], Count(Parts.[Cabinet ID]) as Qty, Parts.Description as Name Parts.Width, Parts.Length
FROM Parts
WHERE PartClass=14 GROUP BY Parts.[Cabinet ID], Parts.Description, Parts.Width, Parts.Length
ORDER BY Parts.[Cabinet ID]
DoorStiles:
SELECT Parts.[Cabinet ID], Count(Parts.[Cabinet ID]) as Qty, Parts.Description as Name Parts.Width, Parts.Length
FROM Parts
WHERE PartClass=15 GROUP BY Parts.[Cabinet ID], Parts.Description, Parts.Width, Parts.Length
ORDER BY Parts.[Cabinet ID]
This gives me three separate views that hold only the parts that I want. Now, I have an additional table:
TableName: Doors
Cabinet ID - Number
Door ID - Number
Width - Number (double)
Height - Number (double)
I use another query to create a view for this as well:
SELECT Doors.[Cabinet ID], Count(Doors.[Door ID]) as Qty FROM Doors GROUP BY Doors.[Cabinet ID] ORDER BY Doors.[Cabinet ID]
So, finally I want to join all of these together...but this is where I am at a bit of a loss. What I need to get, would be a result like this, from the data that I have retrieved:
Doors.[Cabinet ID] Doors.Qty DoorRails.* DoorStiles.* DoorPanels*
1 2 [data] [data] [data]
[data] [data] [data]
2 3 [data] [data] [data]
[data] [data] [data]
[data] [data] [data]
Now, to decipher what I am talking about in the result above, you can see that for [Cabinet ID] 1, I have a door quantity of 2, so I need 2 records for the parts for that door. [Cabinet ID] 2 has 3 doors, so I need 3 records for all the door parts for that.
Now, I understand that this is a little complicated, and possibly...well...impossible, but I have been working on this for a few days and haven't come up with anything. If it's not possible, I would appreciate the experts here telling me so.
Just for FYI - I can't make ANY changes to the database or the structure, all that I can do is run Queries against it.
I think the easiest way to do this would be via a Cartesian join to a table that simply has rows with a single field incrementing from 1 to the maximum number of doors you will ever need. For example,
Counter.Num
-----------
1
2
3
If you cannot even create local tables for your own use, you could simulate the above using a UNION query. Access has some limitations here, so you'll need to reference an existing table even though you won't use any of its rows. For example,
SELECT TOP 1 1 AS Num FROM msysobjects
UNION ALL
SELECT TOP 1 2 AS Num FROM msysobjects
UNION ALL
SELECT TOP 1 3 AS Num FROM msysobjects
Then use this Counter table/query as follows:
SELECT D.[Cabinet ID], C.Num & " of " & Count(D.[Door ID]) AS [Door Number],
DR.*, DS.*, DP.*
FROM Counter AS C,
((Doors AS D INNER JOIN DoorRails AS DR ON D.CabinetID=DR.CabinetID)
INNER JOIN DoorStiles AS DS ON D.CabinetID=DS.CabinetID)
INNER JOIN DoorPanels AS DP ON D.CabinetID=DP.CabinetID
WHERE C.Num <= Count(D.[Door ID])
GROUP BY D.[Cabinet ID]
ORDER BY D.[Cabinet ID], C.Num
This will be a slightly different result than your sample. The difference is the Cabinet ID will be repeated for each door. Since the quantity would also be repeated, I substituted the door number instead (in the form of "1 of 2", "2 of 2", etc.).