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

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;

Related

looking for values from another table where they do not exist in a given group

I have two tables:
SHOPPING
date
id_customer
id_shop
id_fruit
28.03.2018
7423
123
1
13.02.2019
8408
354
1
28.03.2019
7767
123
9
13.02.2020
8543
472
7
28.03.2020
8640
346
9
13.02.2021
7375
323
9
28.03.2021
7474
323
8
13.02.2022
7476
499
1
28.03.2022
7299
123
4
13.02.2023
8879
281
2
28.03.2023
8353
452
1
13.02.2024
8608
499
6
28.03.2024
8867
318
1
13.02.2025
7997
499
6
28.03.2025
7715
499
4
13.02.2026
7673
441
7
FRUITS
id_fruit
name
1
apple
2
pear
3
grape
4
banana
5
plum
6
melon
7
watermelon
8
orange
9
pineapple
I would like to find fruits that have never been bought in a specific id_shop
I tried with this:
SELECT
s.idshop,
s.id_fruit ,
f.name
FROM
shopping s
LEFT JOIN fruit f ON f.id_fruit = s.id_fruit
WHERE NOT EXISTS (
SELECT *
FROM
fruit f1
WHERE f1.id_fruit = s.id_fruit
)
but it does not work...
Yes, you need an OUTER JOIN, but that should be RIGHT JOIN along with NULL values picked from shopping table after join applied, considering your current query such as
SELECT f.*
FROM shopping s
RIGHT JOIN fruit f
ON f.id_fruit = s.id_fruit
WHERE s.id_fruit IS NULL
Demo

MS Access SQL Query unmatched rows from two tables

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.

Oracle : Generate rows with slightly different values in a column

I have a table with data like below :
ID SUMMARY_DATE KEYWORD_ID DATA
123 9/1/2014 5 98
I need to generate 18 more rows with the summary_date + 18 months, something like below :
ID SUMMARY_DATE KEYWORD_ID DATA
123 9/1/2014 5 98
123 10/1/2014 5 98
123 11/1/2014 5 98
123 12/1/2014 5 98
...
123 3/1/2016 5 98
I could do that using UNION but it will be so long. Is there any other ways to do it?
Thanks in advance.
Just generate a list of numbers and use add_months():
with n as (
select level as m
from dual
connect by level <= 18
)
select t.id, add_months(t.summary_date, n.m, keywork_id, data
from table t cross join
n;

Need to join three tables. Not sure which join fits the req

table 1
AcctNO CustomerId Role Name
1 123 A ABC
2 121 B BCA
3 321 C CBA
table 2
AcctNo CustomerId Role Address
1 123 A 1/12
2 121 B 11/3
4 231 C 12-1
3 321 C 111
5 221 C 121
table 3
AcctNo CustomerId Role CompanyName
4 231 C hello
5 221 C bello
3 321 C cello
output should be as follows
AcctNo CustomerId Role Name Address COmpanyName
1 123 A ABC 1/12 NULL
2 121 B BCA 11/3 NULL
3 321 C CBA 111 cello
4 231 C NULL 12-1 hello
5 221 C NULL 121 bello
Use a left join between the tables on a unique column like the CustomerID.
A left join is used instead of a inner join so you get any missing values as a null instead of missing a record.

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