MS Access SQL Query unmatched rows from two tables - sql

Let's say I have Table_A and Table_B with following rows:
Table_A:
ID PART_ID KIT_ID
---------------------
1 1 340
2 12 340
3 19 340
4 30 340
5 1 348
6 19 348
7 27 348
...
Table_B:
PART_ID REQ
-------------
1 Y
12 Y
19 Y
27 Y
30 Y
...
How do I get the following result in Table_C?
Table_C:
PART_ID KIT_ID
----------------
27 340
12 348
30 348
...
I've tried the Query Wizard with the Unmatched Rows and for some reason cannot get any results that resemble what I need.. E.g., a customer orders a kit and each kit contains a bunch of parts (some required and some not); how do I find the missing parts for each kit?

Generate all combinations for the kits and the parts, then filter out the ones that don't exist:
select k.kit_id, p.part_id
from (select distinct kit_id from table_a) as k, -- no cross join in MS ACCESS
table_b p
where not exists (select 1
from table_a as a
where a.kit_id = k.kit_id and a.part_id = p.part_id
);
You may need the condition REQ = "Y" in the outer where clause. I'm not sure if that is important.

Related

Replace Id of one column by a name from another table while using the count statement?

I am trying to get the count of patients by province for my school project, I have managed to get the count and the Id of the province in a table but since I am using the count statement it will not let me use join to show the ProvinceName instead of the Id (it says it's not numerical).
Here is the schema of the two tables I am talking about
The content of the Province table is as follow:
ProvinceId
ProvinceName
ProvinceShortName
1
Terre-Neuve-et-Labrador
NL
2
Île-du-Prince-Édouard
PE
3
Nouvelle-Écosse
NS
4
Nouveau-Brunswick
NB
5
Québec
QC
6
Ontario
ON
7
Manitoba
MB
8
Saskatchewan
SK
9
Alberta
AB
10
Colombie-Britannique
BC
11
Yukon
YT
12
Territoires du Nord-Ouest
NT
13
Nunavut
NU
And here is n sample data from the Patient table (don't worry it's fake data!):
SS
FirstName
LastName
InsuranceNumber
InsuranceProvince
DateOfBirth
Sex
PhoneNumber
2
Doris
Patel
PATD778276
5
1977-08-02
F
514-754-6488
3
Judith
Doe
DOEJ7712917
5
1977-12-09
F
418-267-2263
4
Rosemary
Barrett
BARR05122566
6
2005-12-25
F
905-638-5062
5
Cody
Kennedy
KENC047167
10
2004-07-01
M
604-833-7712
I managed to get the patient count by province using the following statement:
select count(SS),InsuranceProvince
from Patient
full JOIN Province ON Patient.InsuranceProvince = Province.ProvinceId
group by InsuranceProvince
which gives me the following table:
PatientCount
InsuranceProvince
13
1
33
2
54
3
4
4
608
5
1778
6
25
7
209
8
547
9
649
10
6
11
35
12
24
13
How can I replace the id's with the correct ProvinceShortName to get the following final result?
ProvinceName
PatientCount
NL
13
PE
33
NS
54
NB
4
QC
608
ON
1778
MB
25
SK
209
AB
547
BC
649
YT
6
NT
35
NU
24
Thanks in advance!
So you can actually just specify that in the select. Note that it's best practise to include the thing you group by in the select, but since your question is so specific then...
SELECT ProvinceShortName, COUNT(SS) AS PatientsInProvince
FROM Patient
JOIN Province ON Patient.InsuranceProvince=Province.ProvinceId
GROUP BY InsuranceProvince;
I would suggest:
select pr.ProvinceShortName, count(*)
from Patient p join
Province pr
on p.InsuranceProvince = pr.ProvinceId
group by pr.ProvinceShortName
order by min(pr.ProvinceId);
Notes:
The key is including the columns you want in the select and group by.
You seem to want the results in province number order, so I included an order by.
There is no need to count the non-NULL values of SS. You might as well use count(*).
Table aliases make the query easier to write and to read.
I assume that you need to show the patient count by province.
SELECT
Province.ProvinceShortName AS [ProvinceName]
,COUNT(1) as [PatinetCount]
FROM Patient
RIGHT JOIN Province ON Patient.InsuranceProvince = Province.ProvinceId
GROUP BY ProvinceShortName
Just altering your query to
select ProvinceShortName As PatientCount,count(InsuranceProvince) As PatientCount
from Patient
full JOIN Province ON Patient.InsuranceProvince = Province.ProvinceId
group by ProvinceShortName

How do I change my SQL SELECT GROUP BY query to show me which records are missing a value?

I have a list of codes by area and type. I need to get the unique codes for each type, which I can do with a simple SELECT query with a GROUP BY. I now need to know which area does not have one of the codes. So how do I run a query to group by unique values and tell me how records do not have one of the values?
ID Area Type Code
1 10 A 123
2 10 A 456
3 10 B 789
4 10 B 987
5 10 C 654
6 10 C 321
7 20 A 123
8 20 B 789
9 20 B 987
10 20 C 654
11 20 C 321
12 30 A 137
13 30 A 456
14 30 B 579
15 30 B 789
16 30 B 987
17 30 C 654
18 30 C 321
I can run this query to group them by type and get get the unique codes:
SELECT tblExample.Type, tblExample.Code
FROM tblExample
GROUP BY tblExample.Type, tblExample.Code
This gives me this:
Type Code
A 123
A 137
A 456
B 579
B 789
B 987
C 321
C 654
Now I need to know which areas do not have a given code. For example, Code 123 does not appear for Area 10 and code 137 does not appear for codes 10 and 20. How do I write a query to give me that areas are missing a code? The format of the output doesn't matter, I just need to get the results. I'm thinking the results could be in one column or spread out in multiple columns:
Type Code Missing Areas or Missing1 Missing2
A 123 30 30
A 137 10, 20 10 20
A 456 20 20
B 579 10, 20 10 20
B 789
B 987
C 321
C 654
You can get a list of the missing code/areas by first generating all combinations and then filtering out the ones that exist:
select t.type, c.code
from (select distinct type from tblExample) t cross join
(select distinct code from tblExample) c left join
tblExample e
on t.type = e.type and c.code = e.code
where e.type is null;

Select from table repeat first value for combination of two keys

I would like to transfer some existing data into new data table.
I have table with substitutions:
- ID
- currentItemId
- formerItemId
- contentId
For the same content there is possibility I have multiple entries for combinations currentItemId and formerItemId.
Let me show how it is now:
ID_T1 currentItemId formerItemId contentId
1 100 200 300
2 100 200 301
3 100 200 302
4 105 201 303
5 105 201 304
6 110 205 320
7 111 206 321
8 120 204 322
9 130 208 323
10 130 208 324
Now, I would like to select TOP ID for each combination formerItemId and currentItemId:
ID ID_T1 contentId
1 1 300
2 1 301
3 1 302
4 4 303
5 4 304
6 6 320
7 7 321
8 8 322
9 9 323
10 9 324
Both tables also contains timestamp and some other data - I haven't included that in order example to be more understandable.
I tried self join (no success), nested select (gives me right value for the original combination, but it doesn't repeat, it gives me NULL on ID for other records), but nothing seems to work. Tried something like:
SELECT di1.ID,
(SELECT TOP(1) di1.ID
FROM TABLE
WHERE
di1.currentItemtId = di2.currentItemtId AND di1.formerItemId = di1.formerItemId
) AS repeat
,di2.deleteItemId
,di1.currentitemtId
,di1.formerItemId
,di1.contentId
FROM Table di1
LEFT JOIN
Table di2 ON di1.ID = di2.ID
But this way ID doesn't repeat - I get same values for ID as in ordinary select.
I am using SQL server 2008.
Any help would be greatly appreciated.
Please try:
SELECT
MIN(ID) OVER (PARTITION BY currentItemId, formerItemId) ID,
currentItemId,
formerItemId,
contentId
FROM YourTable
SELECT
ID,
MIN(ID) OVER (PARTITION BY currentItemId, formerItemId) ID_T1,
contentId
FROM YourTable

Access SQL - Select only the last sequence

I have a table with an ID and multiple informative columns. Sometimes however, I can have multiple data for an ID, so I added a column called "Sequence". Here is a shortened example:
ID Sequence Name Tel Date Amount
124 1 Bob 873-4356 2001-02-03 10
124 2 Bob 873-4356 2002-03-12 7
124 3 Bob 873-4351 2006-07-08 24
125 1 John 983-4568 2007-02-01 3
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
So, I would like to obtain only these lines:
124 3 Bob 873-4351 2006-07-08 24
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
Anyone could give me a hand on how I could build a SQL query to do this ?
Thanks !
You can calculate the maximum sequence using group by. Then you can use join to get only the maximum in the original data.
Assuming your table is called t:
select t.*
from t join
(select id, MAX(sequence) as maxs
from t
group by id
) tmax
on t.id = tmax.id and
t.sequence = tmax.maxs

Can't get unique values joining two tables

I have 2 tables that I need to join and select the unique rows from. Here is a sample of my data: (there are more columns)
tbl1:
MB# MBName PCCNo_PRI Primary_IP PCCNo_SEC Secondary_IP ID
100 name 0 10.1.9.10 30 10.1.9.10 1
103 name3 17 10.1.9.27 47 10.1.9.67 4
403 name13 17 10.1.9.27 47 10.1.9.67 14
tbl2:
RTU PCC#_PRI PCC#_SEC STATION ADDRESS
15 0 30 6
52 12 42 1
53* 17 47 1
54 18 48 1
63 9 39 2
69* 17 47 2
I need to join the two tables and get the unique RTU(s) in tbl2 for a given MB# in tbl1.
Query =
SELECT t1.MB#,t2.RTU,t2.[Device Manufacturer],t2.PCC#_PRI,t2.PCC#_SEC,t2.[STATION ADDRESS]
INTO C300_RTU_MASTERBLK_Map
FROM mbm_PCDIMasterBlk_tbl as t1, dbo.WOA_PCC_Conn_tbl as t2
WHERE t1.PCCNo_PRI = t2.PCC#_PRI
I am getting duplicate rows for tbl2 53 and 69 (* above). 53 ends up with 2 entries; one to 103 and one 403 (69 gets same). How can I query this for unique RTU(s) to MB#?
The duplicate rows appears because you join on "17" which gives 2 rows on each side
Then, as it stands, you can't with that SELECT list.
How do you decide which t1.MB# you want for the t2 columns?
There is no secondary JOIN column that I can see.
So the best you can get is use MAX (or MIN) to pick either 403 or 103.
SELECT
MAX(t1.MB#) AS MB#,
t2.RTU,t2.[Device Manufacturer],t2.PCC#_PRI,t2.PCC#_SEC,t2.[STATION ADDRESS]
INTO C300_RTU_MASTERBLK_Map
FROM
dbombm_PCDIMasterBlk_tbl as t1
JOIN
dbo.WOA_PCC_Conn_tbl as t2 ON t1.PCCNo_PRI = t2.PCC#_PRI
GROUP BY
t2.RTU,t2.[Device Manufacturer],t2.PCC#_PRI,t2.PCC#_SEC,t2.[STATION ADDRESS]