Adding Two Columns when a Third Column is Equal - sql

I am doing a left join query to compare the two tables for any values that do not equal each other on f9 and sumoff6 columns ONLY if the F1 columns are the same. If they are different i would like to subtract them.
The results I am getting show equal values that are already on both tables. I need for f1 columns to match on both tables but if their values on the sumoff6 and f9 columns do not match then display them and subtract them. F1 is unique on both tables. Keeep in mind though that there may be more rows in the statement table. I am using MS Access SQL view.
Query
SELECT statement.f1, statement.f9
FROM statement
LEFT JOIN allocation_final ON statement.[f1] = allocation_final[f1]
WHERE [allocation_final].sumoff6 <> statement.f9
Statement table:
f1 f9
-----------------
1 135.58
2 166.30
3 40.22
4 86.46
5 170.33
6 96.40
allocation_final:
f1 SumOff6
--------------
1 135.58
2 166.30
3 40.00
4 86.46
5 170.33
6 40.22
7 22.40
8 70.00
9 96.40
10 50.00
Results
f1 f9
--------------
1 135.58
2 166.3
4 86.46
5 170.33
Update:
The result i want is if f1 = f3 and f3 <> sumoff6 then display the output. As you see below for example it still brings up the result if its the same. Look at the first row, which should not be there because f9 = sumoff6.
query:
SELECT statement.f1, statement.f9, allocation_2.[f3], allocation_2.sumoff6
FROM allocation_2 LEFT JOIN statement ON allocation_2.[f3]=statement.f1
WHERE statement.f9 <> allocation_2.sumoff6
GROUP BY statement.f1, statement.f9, allocation_2.[f3], allocation_2.sumoff6
ORDER BY statement.f1;
Output:
f1 f9 f3 sumoff6
--------------------------------------
123456789 135.58 123456789 135.58
111111111 166.3 111111111 66.3
222222222 86.46 222222222 86.46
333333333 170.33 333333333 170.33
444444444 135.58 444444444 35.58
555555555 125.74 555555555 125.74
666666666 73.49 666666666 23.49
777777777 187.99 777777777 87.99

I think your first query is basically correct. The problem is probably that numbers look the same but are really different Does this fix the problem?
SELECT statement.f1, statement.f9
FROM statement INNER JOIN
allocation_final
ON statement.[f1] = allocation_final[f1]
WHERE ABS([allocation_final].sumoff6 - statement.f9) < 0.01

Related

How can I group and get MS Access query to show only rows with a maximum value in a specified field for a consecutive number of times?

I have a large access table that I need to pull specific data from with a query.
I need to get a list of all the IDs that meet a specific criteria, i.e. 3 months in a row with a cage number less than 50.
The SQL code I'm currently working with is below, but it only gives me which months of the past 3 had a cage number below 50.
SELECT [AbBehWeeklyMonitor Database].AnimalID, [AbBehWeeklyMonitor Database].Date, [AbBehWeeklyMonitor Database].Cage
FROM [AbBehWeeklyMonitor Database]
WHERE ((([AbBehWeeklyMonitor Database].Date)>=DateAdd("m",-3,Date())) AND (([AbBehWeeklyMonitor Database].Cage)<50))
ORDER BY [AbBehWeeklyMonitor Database].AnimalID DESC;
I would need it to look at the past 3 months for each ID, and only output if all 3 met the specific criteria, but I'm not sure where to go from here.
Any help would be appreciated.
Data Sample:
Date
AnimalID
Cage
6/28/2022
12345
50
5/19/2021
12345
32
3/20/2008
12345
75
5/20/2022
23569
4
8/20/2022
23569
4
5/20/2022
44444
71
8/1/2012
44444
4
4/1/2022
78986
30
1/20/2022
78986
1
9/14/2022
65659
59
8/10/2022
65659
48
7/14/2022
65659
30
6/14/2022
95659
12
8/14/2022
91111
51
7/14/2022
91111
5
6/14/2022
91111
90
8/14/2022
88888
4
7/14/2022
88888
5
6/14/2022
88888
15
Consider:
Query1:
SELECT AnimalID, Count(*) AS Cnt
FROM Table1
WHERE (((Cage)<50) AND (([Date]) Between #6/1/2022# And #8/31/2022#))
GROUP BY AnimalID
HAVING (((Count(*))=3));
Query2
SELECT Table1.*
FROM Query1 INNER JOIN Table1 ON Query1.AnimalID = Table1.AnimalID
WHERE ((([Date]) Between #6/1/2022# And #8/31/2022#));
Output:
Date AnimalID Cage
6/14/2022 65659 12
7/14/2022 65659 30
8/10/2022 65659 48
6/14/2022 88888 15
7/14/2022 88888 5
8/14/2022 88888 4
Date is a reserved word and really should not use reserved words as names.

Sql – dividing of two results from select count query

I have a table tbl_casebase :
kd_casebase kd_penyakit kd_gejala
---------------------------------
1 P01 G01
3 P01 G03
4 P02 G03
5 P02 G04
6 P03 G04
7 P03 G05
8 P03 G06
9 P03 G07
10 P04 G07
11 P04 G08
12 P05 G08
13 P05 G09
14 P05 G10
15 P06 G10
16 P06 G11
17 P06 G12
18 P07 G12
19 P07 G13
20 P07 G14
21 P07 G15
22 P08 G15
23 P08 G16
24 P09 G17
25 P09 G18
I execute first select count query :
SELECT
kd_penyakit, COUNT(kd_penyakit) AS count1
FROM
tbl_casebase
WHERE
kd_gejala = 'G01' OR kd_gejala = 'G03'
GROUP BY
kd_penyakit
Then I execute second select count query :
SELECT
kd_penyakit, COUNT(kd_penyakit) AS count2
FROM
tbl_casebase
GROUP BY
kd_penyakit
Now what I want to do is dividing both of the results, so should be like this :
Result #1:
kd_penyakit count1
-------------------
P01 2
P02 1
Result #2:
kd_penyakit count2
-------------------
P01 2
P02 2
P03 4
P04 2
P05 3
P06 3
P07 4
P08 2
P09 2
And the divide process is like this :
2/2=1
1/2=0,5
0/4=0
0/2=0
0/3=0
and others
So how to write the query?
I've seen similar post btw but it does not match what I want.
You can use conditional counting - conditional statement within the count() function. Count function counts any non-null value, so if the criteria are met, a non-null value is returned, otherwise null. This way there is no need for subqueries and joins:
SELECT kd_penyakit, COUNT(case when kd_gejala in ('G01','G03') then 1 else null end)/COUNT(kd_penyakit) AS count1
FROM tbl_casebase
GROUP BY kd_penyakit

Why is T-SQL Returning Duplicate Rows, Join Issue I Believe

The code as written below returns the appropriate customers, lockers, units and balance. However, when I add in the commented-out code it reiterates each customer's data for each club even though each customer can only be a member of one club.
USE db1
GO
SELECT [db1].[dbo].[Customer].[CustomerNumber] AS 'Customer No.'
-- ,A. ClubID AS 'Club ID No.'
,(SELECT CONCAT (SI.Locker, '-', SI.Frequency)) AS Locker
,SI.Unit AS Unit
--,[db2].[dbo].[vueClub].Club_aka AS Club
,[db1].[dbo].[Customer_Balance].[CurrentBalance]
FROM [db1].[dbo].[Customer_Balance]
JOIN [db1].[dbo].[Customer]
ON [db1].[dbo].[Customer_Balance].POSCusNo = Customer.CustomerNumber
JOIN [SQLSrv01].[ db3].[dbo].[md_Table_1] AS D
ON D.Contract_no = [db1].[dbo].[Customer_Balance]. POSCusNo
JOIN [SQLSrv01].[ db2].[dbo].[vueSoldLockers] AS SI
ON SI.CustomerID = [db1].[dbo].[Customer].CustomerID
--JOIN [db2].[dbo].[vueClub] AS A
--ON [db1].[dbo].[Customer].SiteID = A.SiteID
WHERE [db1].[dbo].[Customer_Balance].StatusCode = '1234'
ORDER BY Customer.CustomerNumber ASC
So if I run it as is I get:
Customer No. Locker Unit Current Balance
1 315 A1 456.00
2 316 A3 1204.70
3 317 B2 335.60
4 318 B4 1500.30
But if I include the commented-out code I get:
Customer No. Club ID No Locker Unit Club Current Balance
1 4 315 A1 Tigers 456.00
1 3 315 A1 Lions 456.00
2 4 316 A3 Tigers 1204.70
2 3 316 A3 Lions 1204.70
3 4 317 B2 Tigers 335.60
3 3 317 B2 Lions 335.60
4 4 318 B4 Tigers 1500.30
4 3 318 B4 Lions 1500.30
Is it because I don't have the JOIN set up properly?
Customer No. Club ID No Locker Unit Club Current Balance
1 4 315 A1 Tigers 456.00
1 3 315 A1 Lions 456.00
You are joining customer to vueClub on SiteID. Looks like the site customer 1 is in, has 2 clubs (3, 4)

SQL: Counting and Numbering Duplicates - Optimising Correlated Subquery

In an SQLite database I have one table where I need to count the duplicates across certain columns (i.e. rows where 3 particular columns are the same) and then also number each of these cases (i.e. if there are 2 occurrences of a particular duplicate, they need to be numbered as 1 and 2). I'm finding it a bit difficult to explain in words so I'll use a simplified example below.
The data I have is similar to the following (first line is header row, table is referenced in following as "idcountdata"):
id match1 match2 match3 data
1 AbCde BC 0 data01
2 AbCde BC 0 data02
3 AbCde BC 1 data03
4 AbCde AB 0 data04
5 FGhiJ BC 0 data05
6 FGhiJ AB 0 data06
7 FGhiJ BC 1 data07
8 FGhiJ BC 1 data08
9 FGhiJ BC 2 data09
10 HkLMop BC 1 data10
11 HkLMop BC 1 data11
12 HkLMop BC 1 data12
13 HkLMop DE 1 data13
14 HkLMop DE 2 data14
15 HkLMop DE 2 data15
16 HkLMop DE 2 data16
17 HkLMop DE 2 data17
And the output I need to generate for the above would be:
id match1 match2 match3 data matchid matchcount
1 AbCde BC 0 data01 1 2
2 AbCde BC 0 data02 2 2
3 AbCde BC 1 data03 1 1
4 AbCde AB 0 data04 1 1
5 FGhiJ BC 0 data05 1 1
6 FGhiJ AB 0 data06 1 1
7 FGhiJ BC 1 data07 1 2
8 FGhiJ BC 1 data08 2 2
9 FGhiJ BC 2 data09 1 1
10 HkLMop BC 1 data10 1 3
11 HkLMop BC 1 data11 2 3
12 HkLMop BC 1 data12 3 3
13 HkLMop DE 1 data13 1 1
14 HkLMop DE 2 data14 1 4
15 HkLMop DE 2 data15 2 4
16 HkLMop DE 2 data16 3 4
17 HkLMop DE 2 data17 4 4
Previously I was using a couple of correlated subqueries to achieve this as follows:
SELECT id, match1, match2, match3, data,
(SELECT count(*) FROM idcountdata d2
WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3
AND d2.id<=d1.id)
AS matchid,
(SELECT count(*) FROM idcountdata d2
WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3)
AS matchcount
FROM idcountdata d1;
But the table has over 200,000 rows (and the data can be variable in length/content) and hence this takes hours to run. (Strangely, when I first used the same query on the same data back in mid-to-late 2013 it took minutes rather than hours, but that is beside the point - even back then I thought it was inelegant and inefficient.)
I've already converted the correlated subquery for "matchcount" in the above to an uncorrelated subquery with a JOIN as follows:
SELECT d1.id, d1.match1, d1.match2, d1.match3, d1.data,
matchcount
FROM idcountdata d1
JOIN
(SELECT id,match1,match2,match3,count(*) matchcount
FROM idcountdata
GROUP BY match1,match2,match3) d2
ON (d1.match1=d2.match1 and d1.match2=d2.match2 and d1.match3=d2.match3);
So it's just the subquery for "matchid" that I would like some help to optimise.
In short, the following query runs too slowly for larger datasets:
SELECT id, match1, match2, match3, data,
(SELECT count(*) FROM idcountdata d2
WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3
AND d2.id<=d1.id)
matchid
FROM idcountdata d1;
How can I improve the performance of the above query?
It doesn't have to run in seconds, but it needs to be minutes rather than hours (for around 200,000 rows).
A self join may be faster than a correlated subquery
SELECT d1.id, d1.match1, d1.match2, d1.match3, d1.data, count(*) matchid
FROM idcountdata d1
JOIN idcountdata d2 on d1.match1 = d2.match1
and d1.match2 = d2.match2
and d1.match3 = d2.match3
and d1.id >= d2.id
GROUP BY d1.id, d1.match1, d1.match2, d1.match3, d1.data
This query can take advantage of a composite index on (match1,match2,match3,id)

SQL - Datediff between rows with Rank Applied

I am trying to work out how to to apply a datediff between rows where a rank is applied to the USER ID;
Example of how the data below;
UserID Order Number ScanDateStart ScanDateEnd Minute Difference Rank | Minute Difference Rank vs Rank+1
User1 10-24 10:20:00 10:40:00 20 1 | 5
User1 10-25 10:45:00 10:50:00 5 2 | 33
User1 10-26 11:12:00 11:45:00 33 3 | NULL
User2 10-10 00:09:00 00:09:20 20 1 | 4
User2 10-11 00:09:24 00:09:25 1 2 | 15
User2 10-12 00:09:40 00:10:12 32 3 | 3
User2 10-13 00:10:15 00:10:35 20 4 | NULL
What i'm looking for is how to code the final column of this table.
The rank is applied to UserID ordered by ScanDateStart.
Basically, i want to know the time between the ScanDateEnd of Rank 1, to ScanDateStart of Rank2, and so on, but for each user.... (calculating time between order processing etc)
Appreciate the help
This can be achieved by performing a LEFT JOIN to the same table on the UserID column and the Rank column, plus 1.
The following (simplified) pseudo-code should illustrate how to achieve this:
SELECT R.UserID,
R.Rank,
R1.Diff
FROM Rank R
LEFT JOIN Rank R1 ON R1.UserID = R.UserID AND R1.Rank = R.Rank + 1
Effectively, you are showing the UserID and Rank from the current row, but the Difference from the row of the same UserID with the Rank + 1.