Two queries when Joined together adds more records and duplicates records - sql

I have two queries. First Query: Raw data for the clock in. Second Query: Raw data for the clock out. When i combined the two queries together i get duplicated records. On my Raw Check in there are only 2 records and for my clock out query there are 6 records. When I combine the two Queries together i get the total of 12 records with a lot of duplicated entries on both sides.
First Query Code:
SELECT USERINFO.Badgenumber, USERINFO.name, DateValue([Time]) AS DateValue, TimeValue([Time]) AS TimeValue, acc_monitor_log.device_name, Dev.ClockINOut
FROM (Dev INNER JOIN acc_monitor_log ON Dev.DeviceName = acc_monitor_log.device_name) INNER JOIN USERINFO ON acc_monitor_log.pin = USERINFO.Badgenumber
WHERE (((USERINFO.name) Is Null Or (USERINFO.name) Like "*" & [Forms]![Query].[NameQ] & "*") AND ((DateValue([Time]))>=[Forms]![Query]![StartDateQ] And (DateValue([Time]))<=[Forms]![Query]![EndDateQ]) AND ((TimeValue([Time]))>=[Forms]![Query]![StartTimeQ] And (TimeValue([Time]))<=[Forms]![Query]![EndTimeQ]) AND ((Dev.ClockINOut)="Clock In"))
ORDER BY USERINFO.name, DateValue([Time]);
Second Query Code:
SELECT USERINFO.Badgenumber, USERINFO.name, DateValue([Time]) AS DateValue, TimeValue([Time]) AS TimeValue, acc_monitor_log.device_name, Dev.ClockINOut
FROM (Dev INNER JOIN acc_monitor_log ON Dev.DeviceName = acc_monitor_log.device_name) INNER JOIN USERINFO ON acc_monitor_log.pin = USERINFO.Badgenumber
WHERE (((USERINFO.name) Is Null Or (USERINFO.name) Like "*" & Forms!Query.NameQ & "*") And ((DateValue([Time]))>=Forms!Query!StartDateQ And (DateValue([Time]))<=Forms!Query!EndDateQ) And ((TimeValue([Time]))>=Forms!Query!StartTimeQ And (TimeValue([Time]))<=Forms!Query!EndTimeQ) And ((Dev.ClockINOut)="Clock Out"))
ORDER BY USERINFO.name, DateValue([Time]);
And the Combined Query of the two above queries:
SELECT RQOut.Badgenumber, RQOut.name, RQOut.DateValue, RQOut.TimeValue, RQOut.ClockINOut, RQIn.TimeValue, RQIn.device_name, RQIn.ClockINOut, [RQIn].[TimeValue]-[RQOut].[TimeValue] AS Timess
FROM RQOut INNER JOIN RQIn ON (RQOut.Badgenumber = RQIn.Badgenumber) AND (RQOut.name = RQIn.name) AND (RQOut.DateValue = RQIn.DateValue)
WHERE (((RQOut.name) Is Null Or (RQOut.name) Like "*" & [Forms]![Query].[NameQ] & "*") AND ((RQOut.DateValue)>=[Forms]![Query]![StartDateQ] And (RQOut.DateValue)<=[Forms]![Query]![EndDateQ]) AND ((RQOut.TimeValue)>=[Forms]![Query]![StartTimeQ] And (RQOut.TimeValue)<=[Forms]![Query]![EndTimeQ]))
ORDER BY RQOut.TimeValue, RQIn.TimeValue;
Please can anyone tell me why i am getting this. Thanks in advance.

INNER JOIN between two data sets returns records from both data sets where the fields match. If one record in the first data set matched 10 records (say) in the second dataset, it returns 10 records.
This is effectively the process the inner join is following in your last query: It will look at record 1 of RQin, then search for matching records in RQout. For the fields you asked to match up, ALL of the records in RQOut will be returned, because the fields you joined on match up for ALL the records. It then does the same for record 2 in RQIn, and again it matches with ALL the records on RQOut. This means you get 2 x 6 = 12 records returned.

Related

How to select all rows that are related to satisfied condition in ms ACCESS

I have the following data in table VehiclesAccSummary:
I am not sure how to do this but what I want is a query that would return all rows where there where only two car in the accident and it was a head on crash so in both cars PointOfImpact was 'Front' i know in need to do some inner join on the same table but i don' want to join same car with it self. Any idea ?
The end result should be something like this
You can use a subquery to count the number of "Front' records for each AccRef.
SELECT *
FROM VehiclesAccSummary INNER JOIN
(SELECT VehiclesAccSummary.AccRef, Count(VehiclesAccSummary.PointOfImpact) AS CountOfPointOfImpact FROM VehiclesAccSummary GROUP BY VehiclesAccSummary.AccRef, VehiclesAccSummary.PointOfImpact HAVING VehiclesAccSummary.PointOfImpact="Front") AS FrontCount
ON VehiclesAccSummary.AccRef = FrontCount.AccRef
WHERE VehiclesAccSummary.NumCars = 2 AND CountOfPointOfImpact = 2;
This will limit the records to AccRefs with NumCar = 2 and the count of Front records = 2.
Edit: Since the same car can be listed in multiple records, we need a new approach. Try this:
SELECT VehiclesAccSummary.*, Subquery.CountOfPointOfImpact
FROM VehiclesAccSummary LEFT JOIN (SELECT VehiclesAccSummary.AccRef, Count(VehiclesAccSummary.PointOfImpact) AS CountOfPointOfImpact
FROM VehiclesAccSummary
WHERE (((VehiclesAccSummary.PointOfImpact)<>"Front"))
GROUP BY VehiclesAccSummary.AccRef) AS Subquery ON VehiclesAccSummary.AccRef = Subquery.AccRef
WHERE (((Subquery.CountOfPointOfImpact) Is Null));
Instead of confirming that the count of front accidents is 2, this confirms that the count of non-front accidents is 0.

returning one row, with the max date from two different columns from two different tables

Using report builder 3.0 for sql server 08 R2. Trying to get the most recent dates from 2 different columns in 2 different tables but I'm getting 4 rows instead of 1. In the picture below, there should be one row per patient.
Script I'm using is this:
SELECT "Patient"."PatientID", "PatientLastName", "PatientFirstName", "DischargeDate", "PatVisitPayable"."ContactDate"
FROM "BTI"."Patient"
JOIN "BTI"."PatAdmissions" ON "Patient"."PatientID" = "PatAdmissions"."PatientID"
JOIN "BTI"."PatVisitPayable" ON "PatAdmissions"."PatientID" = "PatVisitPayable"."PatientID"
JOIN "BTI"."PatAdmissionDivision" ON "PatAdmissions"."AdmissionID" = "PatAdmissionDivision"."AdmissionID"
GROUP BY "Patient"."PatientID", "PatientLastName", "PatientFirstName", "DischargeDate", "ContactDate"
I've tried putting max(contactdate) and max(dischargedate) in the select statement but still get 4 rows. Wasn't sure if this is something I should include in the initial query or something I can add to the report afterwards.
4 rows for one patient
Try to remove ContactDate from GROUP BY clause and use max() function in SELECT :
SELECT pt.PatientID,
pt.PatientLastName, pt.PatientFirstName, pt.DischargeDate,
MAX(ContactDate) as ContactDate
FROM BTI.Patient pt
JOIN BTI.PatAdmissions pa ON pt.PatientID = pa.PatientID
JOIN BTI.PatVisitPayable py ON pa.PatientID = py.PatientID
JOIN BTI.PatAdmissionDivision pd ON pa.AdmissionID = pd.AdmissionID
GROUP BY pt.PatientID, pt.PatientLastName,
pt.PatientFirstName, pt.DischargeDate;
Always define table alise that could be easy to follow/read and write.
This assumes ContactDate in resonbale format.

Oracle SQL query that deals with inner Joins and values

SELECT sc.TAAC_SHARE_CLASS_ID,
SCS.SHARE_CLASS_SID,
SCS.REPORTING_DT,
SCS.SHARE_CLASS_SNAPSHOT_SID,
SCS.DIST_UNMOD_30_DAY_YIELD_PCT,
SCS.DER_DIST_12_MO_YIELD_PCT,
SCS.DER_SEC_30_DAY_YIELD_PCT AS SCS_DER_SEC_30_DAY_YIELD_PCT,
SCS.DER_SEC_RESTATED_YIELD_PCT AS SCS_DER_SEC_RESTATED_YIELD_PCT
FROM SHARE_CLASS sc
INNER JOIN PORTFOLIO P ON (P.PORTFOLIO_SID=SC.PORTFOLIO_SID)
INNER JOIN SHARE_CLASS_SNAPSHOT SCS ON
(SCS.SHARE_CLASS_SID=sc.SHARE_CLASS_SID)
WHERE SCS.REPORTING_DT = '24-JUL-17' AND P.PORTFOLIO_ID = 638;
I ran this query and got the following output : image
Here, instead of getting separate rows for the same TAAC_SHARE_CLASS_ID, I want to merge the outputs of same TAAC_SHARE_CLASS_ID.
For example, the first row with TAAC_SHARE_CLASS_ID = 000648 should have values for all the 4 columns :
SCS.DIST_UNMOD_30_DAY_YIELD_PCT,
SCS.DER_DIST_12_MO_YIELD_PCT,
SCS.DER_SEC_30_DAY_YIELD_PCT,
SCS.DER_SEC_RESTATED_YIELD_PCT.
Hence the first row should have values for those columns as 2.96,3.2972596, 7541.085263433, 7550.
The last 4 rows of my output are not really required, as we have now merged those data into first 4 rows correspondingly.
How can I alter this query to achieve the same? Please help.
I suggest you group your results by TAAC_SHARE_CLASS_ID column, and MAX() the remaining columns, something like this:
SELECT sc.TAAC_SHARE_CLASS_ID,
max(SCS.SHARE_CLASS_SID) as SHARE_CLASS_SID,
max(SCS.REPORTING_DT) as REPORTING_DT,
max(SCS.SHARE_CLASS_SNAPSHOT_SID) as SHARE_CLASS_SNAPSHOT_SID,
max(SCS.DIST_UNMOD_30_DAY_YIELD_PCT) as DIST_UNMOD_30_DAY_YIELD_PCT,
max(SCS.DER_DIST_12_MO_YIELD_PCT) as DER_DIST_12_MO_YIELD_PCT,
max(SCS.DER_SEC_30_DAY_YIELD_PCT) AS SCS_DER_SEC_30_DAY_YIELD_PCT,
max(SCS.DER_SEC_RESTATED_YIELD_PCT) AS SCS_DER_SEC_RESTATED_YIELD_PCT
FROM SHARE_CLASS sc
INNER JOIN PORTFOLIO P ON (P.PORTFOLIO_SID=SC.PORTFOLIO_SID)
INNER JOIN SHARE_CLASS_SNAPSHOT SCS ON (SCS.SHARE_CLASS_SID=sc.SHARE_CLASS_SID)
WHERE SCS.REPORTING_DT = '24-JUL-17' AND P.PORTFOLIO_ID = 638
GROUP BY sc.TAAC_SHARE_CLASS_ID;

MS Access SQL: Enumerate results from a many-to-one relationship

Very simply, I have a many-to-one relationship table set in MS Access where I've managed to pull out the distinct values as separate rows. I now need to enumerate these rows.
The query looks like the following (generated by the MS Access Designer - apologies for the formatting):
SELECT DISTINCT ValidationRule.ValidationCode AS Rule, Table.Template AS Template
FROM ValidationRule RIGHT JOIN (([Table] INNER JOIN TableVersion ON Table.TableID = TableVersion.TableID) INNER JOIN ValidationScope ON TableVersion.TableVID = ValidationScope.TableVID) ON ValidationRule.ValidationId = ValidationScope.ValidationID
GROUP BY ValidationRule.ValidationCode, Table.Template
ORDER BY ValidationRule.ValidationCode;
So my data looks like:
Rule Template
v0007_m C 00.01
v0189_h C 01.00
v0189_h C 05.01
v3000_i C 08.00
I need to add sequential values to the results as follows:
Rule Template Sequence
v0007_m C 00.01 1
v0189_h C 01.00 1
v0189_h C 05.01 2
v3000_i C 08.00 1
What function should I be looking at in MS Access SQL to do this?
If you save the query you have as a separate query called qryValdationRule, this query which builds off that should give you what you need:
SELECT qryValidationRule.Rule, qryValidationRule.Template, DCount("*", 'qryValidationRule', "[Rule] = '" & qryValidationRule.Rule & "' AND [Template] <= '" & qryValidationRule.Template & "'") AS Sequence
FROM qryValidationRule
ORDER BY qryValidationRule.Rule, qryValidationRule.Template;
We are looking up and getting a count of all records with the same Rule value with an equal or less Template value within the dataset. This, essentially, gives us a Sequence grouped by Rule. This only works properly if Template values are distinct across Rule groups, which should be the case because you are pulling a DISTINCT across the CROSS JOIN of tables. It is not as convenient or flexible as window functions, but will get you what you need.
You may also want to try this method, which may be more efficient:
SELECT t1.Rule, t1.Template, COUNT(t2.Template) AS Sequence
FROM qryValidationRule AS t1 INNER JOIN qryValidationRule AS t2 ON t1.Rule = t2.Rule AND t1.Template >= t2.Template
GROUP BY t1.Rule, t1.Template
ORDER BY t1.Rule, t1.Template;
EDIT: Added an alternative way to find the same data; may be more performant because of JOINing vs. subqueries.
Use: Count(*) AS Sequence
SELECT DISTINCT ValidationRule.ValidationCode AS Rule, Table.Template AS Template, Count(*) AS Sequence
FROM ValidationRule RIGHT JOIN (([Table] INNER JOIN TableVersion ON Table.TableID = TableVersion.TableID) INNER JOIN ValidationScope ON TableVersion.TableVID = ValidationScope.TableVID) ON ValidationRule.ValidationId = ValidationScope.ValidationID
GROUP BY ValidationRule.ValidationCode, Table.Template
ORDER BY ValidationRule.ValidationCode;

SQL Query - Distinct doesn't seem to filter

I'm utilizing four separate tables and i can't seem to figure out why my DISTINCT isn't filtering the results. I'm trying to get a single result for each acct.Name in this query. Regardless if i use DISTINCT or not, i get the exact same results.
Select DISTINCT
acct.Name,
inv.InvoiceNumber,
acct.AccountNumber,
addr.Line1,
addr.Line2,
addr.Line3,
addr.City,
addr.StateOrProvince,
addr.postalcode
FROM InvoiceBase inv, AccountBase acct
JOIN AccountExtensionBase base
ON base.AccountId = acct.AccountId
JOIN CustomerAddressBase addr
ON addr.ParentId = acct.AccountId
WHERE
inv.AccountId=acct.AccountId And
base.New_cocat_master = 1 And
base.New_CompanyId = 1 And
inv.StateCode = 0 And
inv.Name = '2013 ' + acct.AccountNumber
ORDER by acct.Name
The first result i get now has the first three values (acct.Name, inv.InvoiceNumnber, acct.AccountNumber) and the rest of the columns are blank. The second row has all of the columns with the information. I'm just trying to make the acct.Name to be DISTINCT
The rows are DISTINCT
This may be confusing when you are selecting multiple strings, since there might be hidden characters/spaces. Select the length of each one of those fields and compare the so called duplicate rows.
Turns out all i had to do was add in a simple clause in the WHERE, since the address is required for a valid invoice (where to send it):
WHERE
base.New_cocat_master = 1 And
base.New_CompanyId = 1 And
inv.StateCode = 0 And
inv.Name = '2013 ' + acct.AccountNumber And
addr.Line1 IS NOT NULL