SQL Server: Updating a column - sql

I have a TblA
ID Match Code Status
1 001 A
2 001 B
3 002 A
4 003 A
5 003 V
6 004 A
7 004 B
I want to populate Status with 'FAIL' according to :
Code "A" and "B" should both exist for every match number. For 001,002,003 both A, B should exist. if not, FAIL the whole Match. Expected table:
ID Match Code Status
1 001 A NULL
2 001 B NULL
3 002 A FAIL
4 003 A FAIL
5 003 V FAIL
6 004 A NULL
7 004 B NULL
Thanks !

Here you go:
update [TblA]
set [Status] = 'FAIL' where
Match NOT in
(select match from tblA where Code = 'A'
intersect
select match from tblA where Code = 'B');

Related

Splitting a row into multiple rows based on quantity and increment a value (SQL Access)

I want to split a row into multiple rows according to a column named "Qta" and incrementing a serial number named "S/N", so:
Name S/N Qta
A 004 1
B 005 1
C 007 3
D 004 1
Will become:
Name S/N Qta
A 004 1
B 005 1
C 007 1
C 008 1
C 009 1
D 004 1
I'm using Microsoft Access
I managed to split the rows, but i see no way to increment serial number
Here's my query:
SELECT *
FROM Num AS N INNER JOIN MergedQueries1 AS t ON n.numbers<=t.Qta;
Obviously i created another table containing numbers
Consider:
SELECT T.Name, Format(T.SN + N.Num - 1,"000") AS SerNum, 1 AS Q
FROM MergedQueries1 AS T, (SELECT Num FROM Numbers) AS N
WHERE N.Num<=T.Qta ORDER BY T.Name, T.SN + N.Num - 1;

Find duplicate rows and change a value in MS ACCESS

i'm trying to realize a query that find duplicates in a table and increment by 1 their s/n value.
Example:
Name S/N id
A 004 1
B 005 2
C 007 3
C 007 4
C 007 5
D 004 6
Will be:
Name S/N id
A 004 1
B 005 2
C 007 3
C 008 4
C 009 5
D 004 6
I'm using ms access.
Okay then assuming your table is called Table1, you could use the following code:
select
base.[Name]
, base.[S/N]
+ (
select
count(*)
from Table1 as a
where 1=1
and a.[S/N] = base.[S/N]
and a.[Name] = base.[Name]
and base.id >= a.id
)
- 1 as [S/N]
, base.id
from Table1 base
This solution is not performant on huge datasets, but unfortunately there is no row_number() in Access (it's a terrible tool). Basically what it does is create an artificial row number with a partition by Name,S/N and then adds the row number minus 1 to the S/N. So if there is only one entry, then 0 will be added, otherwise the first duplicate gets +1, second +2 etc.
You don't need the 1=1 of course, but it's a habit :)

SQL fill missing date and null value

I am using SAS Enterprise Guide 8.3 to connect IBM DB2.
I want to join and fill missing date and values.
I have a full calendar date table from 1/1/2021 up to yesterday.
Each ID can work 5 days to 7 days a week.
There is no target for Sunday.
4/3/2022 is Sunday.
Code is
SELECT t2.ID,
t1.CAL_DT, COALESCE(t2.EXPRESS,0) AS EXPRESS, COALESCE(t2.OTHRES,0) AS OTHRES , COALESCE(t2.CPRO_RPT,0) AS Total
FROM WORK.QUERY_FOR_DATE t1
left outer JOIN WORK.QUERY_FOR_CPRO_0000 t2 on t1.cal_dt = t2.cal_dt
ORDER BY t2.ID asc ,t1.CAL_DT asc;
Sample tables are below.
Table 1.
ID
Date
Express
Others
Total
001
4/1/2022
0
2
2
001
4/2/2022
2
3
5
001
4/4/2022
1
2
3
001
4/5/2022
2
2
4
002
4/1/2022
0
3
3
002
4/4/2022
3
3
6
002
4/5/2022
1
2
3
003
4/1/2022
3
3
6
003
4/2/2022
4
4
8
003
4/3/2022
1
1
2
003
4/4/2022
3
4
7
003
4/6/2022
2
4
6
Table 2.
ID
Date
Target
001
4/1/2022
4
001
4/2/2022
4
001
4/4/2022
4
001
4/5/2022
4
002
4/1/2022
6
002
4/2/2022
6
002
4/4/2022
6
002
4/5/2022
6
003
4/1/2022
8
003
4/2/2022
8
003
4/4/2022
8
003
4/5/2022
8
I want the result in Table 3.
ID
Date
Express
Others
Total
Target
001
4/1/2022
0
2
2
4
001
4/2/2022
2
3
5
4
001
4/3/2022
0
0
0
0
001
4/4/2022
1
2
3
4
001
4/5/2022
2
2
4
4
002
4/1/2022
0
3
3
6
002
4/2/2022
0
0
0
6
002
4/3/2022
0
0
0
0
002
4/4/2022
3
3
6
6
002
4/5/2022
1
2
3
6
003
4/1/2022
3
3
6
8
003
4/2/2022
4
4
8
8
003
4/3/2022
1
1
2
0
003
4/4/2022
3
4
7
8
003
4/5/2022
2
4
6
8
I would use your date table to cross join with your ID to build a permutation of those two, then you can join ID back into the set and get a full set of ID and Dates along with your real data from your CPRO table. You could join back in again between MIN and MAX date to remove all the dates in your date table.
SELECT X.ID, X.CAL_DT
, COALESCE(T3.EXPRESS,0) EXPRESS
, COALESCE(T3.OTHRES,0) OTHRES
, COALESCE(T3.CPRO_RPT,0) CPRO_RPT
FROM ( SELECT DISTINCT T2.ID, T1.CAL_DT FROM (WORK.QUERY_FOR_DATE t1 CROSS JOIN WORK.QUERY_FOR_CPRO_0000 t2)) X
LEFT OUTER JOIN WORK.QUERY_FOR_CPRO_0000 T3
ON X.ID = T3.ID
AND X.CAL_DT = T3.CAL_DT
You could also add another join to keep you date range correct if you didn't want to hard code it in the where clause.
SELECT
X.ID
, X.CAL_DT
, COALESCE(T3.EXPRESS,0) EXPRESS
, COALESCE(T3.OTHRES,0) OTHRES
, COALESCE(T3.CPRO_RPT,0) CPRO_RPT
FROM
(
SELECT DISTINCT T2.ID, T1.CAL_DT
FROM (WORK.QUERY_FOR_DATE t1
CROSS JOIN WORK.QUERY_FOR_CPRO_0000 t2)) X
LEFT OUTER JOIN WORK.QUERY_FOR_CPRO_0000 T3
ON X.ID = T3.ID
AND X.CAL_DT = T3.CAL_DT
INNER JOIN
(SELECT MIN(DT) AS MINDATE, MAX(DT) AS MAXDATE
FROM WORK.QUERY_FOR_CPRO_000) AS DATEPARAM
ON X.CAL_DT BETWEEN MINDATE AND MAXDATE
Since you have a Calendar table, you may try the following:
Select B.id, C.CAL_DT, COALESCE(D.express, 0) express, COALESCE(D.others, 0) others,
COALESCE(D.total, 0) total, COALESCE(E.target, 0) target
From Calendar C
Cross Join (Select Distinct id From Table1) B
Left Join table1 D
On D.id = B.id And D.date_ = C.CAL_DT
Left Join table2 E
On E.id = B.id And E.date_ = C.CAL_DT
Order By B.id, C.CAL_DT
First, you have to join each id from table1 to every day in your calendar table, and that done by cross join the calendar with the distinct ids from table1.
Now, left join that result to table1, table2 to get which ids not having entries for a specific date (null values).
The COALESCE function is used to replace null values with 0.
See a demo using DB2 from db<>fiddle.

Get ID from Row Number SQL

I have the following table:
Code ParentCode oItem
-----------------------------
A null Item 001
B A Item 002
C A Item 003
D C Item 004
E B Item 005
Now, I want to have the row number then the result should be:
Rn Code ParentCode oItem
------------------------------------------
1 A null Item 001
2 B A Item 002
3 C A Item 003
4 D C Item 004
5 E B Item 005
My question is, How's the query to get the following result:
Rn Code RnParent ParentCode oItem
--------------------------------------------------------
1 A null null Item 001
2 B 1 A Item 002
3 C 1 A Item 003
4 D 3 C Item 004
5 E 2 B Item 005
If you see on the result table, parentcode is actually the code and I need to know the id of the parentcode base on the code of Rn.
Please advise.
Thank you.
If I understand correctly, you just want the rn for the parentcode. You can get this with a join:
with t as (
select row_number() over (order by code) as rn, t.*
from t
)
select t.*, tp.rn as parentrn
from t left join
t tp
on t.parentcode = tp.code

Select distinct values from two different columns of two tables with other non-distinct columns

I'm trying to eliminate duplicate rows from an Access dataset made up of two tables. I want to retrieve the distinct values from one column of two tables, but also retrieve the values of other columns of duplicates and unique values.
The field I want unique values for is [PART-SN] from table2. I want to select all other fields from table1 and [PART-SN] from table 2, of which all rows should be returned for all distinct rows of [PART-SN]. [PART FIND NO] and [PART-ATA-NO] have equivalent values and has duplicates. I've seen posts on how to get values from two tables of the same column. Is there a way to join the two tables to get this result?
Sample data (not actual data):
Table 1:
ID BOM_PART_NAME PART FIND NO POS LCN POS_CT
1 E 0001 1 P0 1
2 A 0002 1 P1 1
3 C 0003 1 P2 1
4 D 0004 1 P3 1
5 F 0005 1 P4 1
Table 2:
ID PART-ATA-NO PART-SN PART-NAME
1 001 A
2 002 B
3 003 C
4 004 1100 D
5 005 1101 E
ID BOM_PART_NAME PART FIND NO POS LCN POS_CT
1 E 0001 1 P0 1
2 A 0002 1 P1 1
3 C 0003 1 P2 1
4 D 0004 1 P3 1
5 F 0005 1 P4 1
Table 2:
ID PART-ATA-NO PART-SN PART-NAME
1 001 A
2 002 B
3 003 C
4 004 1100 D
5 005 1101 E
What I'm getting:
ID ... PART FIND NO POS PART-ATA-NO PART-SN
1 001 1 001 1369
2 002 1 002 1444
3 003 1 003 1100
3 003 1 003 1101
3 003 1 003 1102
4 003 2 003 1101
4 003 2 003 1102
5 004 1 004 1101
5 004 1 004 1102
Desired Result:
ID PART FIND NO POS PART-ATA-NO PART-SN
1 001 1 001 1369
2 002 1 002 1444
3 003 1 003 1100
4 003 2 003 1101
5 003 3 003 1102
6 003 4 003 1103
7 003 5 003 1104
8 004 1 004 1105
9 004 2 004 1106
Open up Access and click on create new query
It will prompt you to select the tables you want to include
Once you have them selected, if they dont already have relationship lines between them, drag/drop the matching fields to create the relationships
Then click on the Sigma symbol to turn on groupings option
Drag the fields you want included down to the area where you set up the output for the query
Then select which fields you want to group by and which fields are the expressions you are trying to get the values for
Run the query and see if you get the results you want
If you dont, fiddle with the options until you get the output you want
Then click the dropdown for the Design/Run button and there will be a SQL option
Click that and it will show you the select statement you want to use
If you want unique values for [PART FIND NO] and [PART-ATA-NO] you can try to do an UNION.
SELECT Table1.[PART FIND NO]
FROM Table1 UNION SELECT Table2.[PART-ATA-NO] As [PART FIND NO] From
Table2;
It's a bit weird, but I have done a test in Access 2016 with values repeated in Table1 and Table2 and even values appearing twice in a Table and the Union only returns the values once.
|Table1|
|AAA|
|BBB|
|CCC|
|Table2|
|AAA|
|BBB|
|AAA|
|DDD|
|Query 1|
|AAA|
|BBB|
|CCC|
|DDD|
Hope it helps
I think the overall question is a duplicate of How do I merge two tables in Access while removing duplicates?
But here is a query specific to your needs.
EDIT: Updated second query to remove Table2.[PART-SN] to eliminate duplicates of merged tables after more information from original poster.
SELECT Table1.*, Table2.[PART-ATA-NO], Table2.[PART-SN]
FROM Table1 INNER JOIN Table2 ON Table1.[PART FIND NO] = Table2.[PART-ATA-NO]
UNION
SELECT Table1.*, Table2.[PART-ATA-NO]
FROM Table1 LEFT JOIN Table2 ON Table1.[PART FIND NO] = Table2.[PART-ATA-NO]
WHERE (((Table2.[PART-ATA-NO]) Is Null))
UNION
SELECT Table1.*, Table2.[PART-ATA-NO], Table2.[PART-SN]
FROM Table1 RIGHT JOIN Table2 ON Table1.[PART FIND NO] = Table2.[PART-ATA-NO]
WHERE (((Table1.[PART FIND NO]) Is Null));
It is likely not possible to fullfil all requirements in one query. The results of one query can feed another query. It is possible to use a saved (i.e. named) queries in the FROM clause of another query (or if in design mode it means you can show and join to other queries just like tables). If eliminating duplicates is the primary concern, then save your modified UNION query (like above), for example named as [Merge1and2].
Assuming that [Merge1And2] now contains only unique [PART FIND NO], you can do something like
SELECT [Merge1And2].[PART FIND NO], Table2.[PART-SN]
FROM [Merge1And2] INNER JOIN Table2 ON [Merge1And2].[PART FIND NO] = Table2.[PART-ATA-NO]
This will give you all the [PART-SN] values for each unique [PART FIND NO]. Of course the results of this second query will no longer show unique [PART FIND NO] values, since the same number can potentially be listed for each [PART-SN] -- at least according to what you commented about [PART-SN] having multiple values per [PART-ATA-NO] in Table2.
If your ultimate goal is to merge the two tables, removing duplicates, BUT you have multiple related values like [PART-SN], then from the information I have you will need more than one table: First a primary table to store the unique part numbers, then a one-to-many relationship on a second table for storing duplicate [PART-SN] (and possibly other) values.