Merge same SQL database values in table and relating table - sql

sure it could solved one by one, for each value in specified column but I was looking for an more elegant way, handled by one SQL query.
Following mini database:
Two material tables:
Table MatA:
ID NomCom_ID ProFo_ID
1 1 1
2 2 2
Table MatB:
ID NomCom_ID ProFo_ID
1 1 2
2 2 2
One note table:
Table Note:
ID Val MatTab
1 S6 A
2 T1 A
3 W10 A
4 W12 A
5 S5 B
6 T1 B
7 G10 B
8 T1 XXX
9 W10 XXX
10 G8 XXX
And one table for relation between notes and Materials:
Table RelateNoteMat:
ID Mat_ID Note_ID
1 1 1
2 1 2
3 2 2
4 2 3
5 1 8
6 1 10
at a later time it's clear, that MatTab 'XXX' is MatTab 'A'
so I want to update Table Note and Table RelateNoteMat like this:
Table Note:
ID Val MatTab
1 S6 A
2 T1 A
3 W10 A
4 W12 A
5 S5 B
6 T1 B
7 G10 B
8 G8 A
And one table for relation between notes and Materials:
Table RelateNoteMat:
ID Mat_ID Note_ID
1 1 1
2 1 2
3 2 2
4 2 3
5 1 8
is this possible with one SQL query?

Related

Add entries of a table into rows of another table

I have two tables
table a:
ID VALUE_z
1 41
2 32
3 51
table b:
ID TYPE z
1 a 10
1 b 15
1 c 20
2 a 12
2 b 8
2 c 5
3 a 21
3 b 4
3 c 2
I want to add the rows from table a to the column VALUE in table b based on the ID. The result should look like this
table result:
ID TYPE VALUE
1 a 10
1 b 15
1 c 20
1 z 41
2 a 12
2 b 8
2 c 5
2 z 32
3 a 21
3 b 4
3 c 2
3 z 51
Try the following using INSERT INTO SELECT Statement:
insert into tableB
select ID, 'z', VALUE_z
from tableA
See demo

SAS - Update table variable with multiple where criteria

Please excuse my lack of knowledge i'm very new to SAS.
I have two tables as exampled below:
T1
ID
Ill_No
1
1
1
1
1
2
1
2
1
3
1
3
2
1
2
1
2
2
2
2
2
3
2
3
T2
ID
Ill_No
1
1
2
3
I want to update the original table with a new variable (MATCH) where both ID and Ill_No match with the second table. Example below:
T1
ID
Ill_No
MATCH
1
1
Y
1
1
Y
1
2
1
2
1
3
1
3
2
1
2
1
2
2
2
2
2
3
Y
2
3
Y
What is the most efficient way to do this?
Perhaps use a simple merge statement
data want;
merge t1(in=one) t2(in=two);
by id III_No;
if one and two then match = 'Y';
run;
ID III_No match
1 1 Y
1 1 Y
1 2
1 2
1 3
1 3
2 1
2 1
2 2
2 2
2 3 Y
2 3 Y

SQL append data based on multiple dates

I have two tables; one contains encounter dates and the other order dates. They look like this:
id enc_id enc_dt
1 5 06/11/20
1 6 07/21/21
1 7 09/15/21
2 2 04/21/20
2 5 05/05/20
id enc_id ord_dt
1 1 03/7/20
1 2 04/14/20
1 3 05/15/20
1 4 05/30/20
1 5 06/12/20
1 6 07/21/21
1 7 09/16/21
1 8 10/20/21
1 9 10/31/21
2 1 04/15/20
2 2 04/21/20
2 3 04/30/20
2 4 05/02/20
2 5 05/05/20
2 6 05/10/20
The order and encounter date can be the same, or differ slightly for the same encounter ID. I'm trying to get a table that contains all order dates before each encounter date. So the data would like this:
id enc_id enc_dt enc_key
1 1 03/7/20 5
1 2 04/14/20 5
1 3 05/15/20 5
1 4 05/30/20 5
1 5 06/11/20 5
1 1 03/7/20 6
1 2 04/14/20 6
1 3 05/15/20 6
1 4 05/30/20 6
1 5 06/12/20 6
1 6 07/21/21 6
1 1 03/7/20 7
1 2 04/14/20 7
1 3 05/15/20 7
1 4 05/30/20 7
1 5 06/12/20 7
1 6 07/21/21 7
1 7 09/15/21 7
2 1 04/15/20 2
2 2 04/21/20 2
2 1 04/15/20 5
2 2 04/21/20 5
2 3 04/30/20 5
2 4 05/02/20 5
2 5 05/05/20 5
Is there a way to do this? I am having trouble figuring out how to append the orders and encounter table for each encounter based on orders that occur before a certain date.
You may join the two tables as the following:
SELECT O.id, O.enc_id, O.ord_dt, E.enc_id
FROM
order_tbl O
JOIN encounter_tbl E
ON O.ord_dt <= E.enc_dt AND
O.id = E.id
See a demo from db<>fiddle.

Return unique combinations from many to many join

I have a hierarchy table with the following data :
SOURCE TARGET Level ID
0 1 1 1
0 2 1 2
2 3 2 3
2 4 2 4
2 5 2 5
1 3 2 6
1 4 2 7
1 5 2 8
5 3 3 9
5 3 3 10
4 3 3 11
4 3 3 12
3 6 3 13
3 6 3 14
3 6 4 15
3 6 4 16
3 6 4 17
3 6 4 18
The SOURCE and TARGET rows are the original data and are used to connect between parents and children. for example, the third row (SOURCE 2, TARGET 3 on LEVEL 2) connects to the second row (SOURCE 0, TARGET 2 on LEVEL 1) since the Source of the first equals the target of the second.
The ID column is added at the end using a ROW_NUMBER function and is used to give each row a unique ID.
It may be easier to understand if SOURCE is replaced with PARENT and TARGET with CHILD.
I join the table to itself in order to find the "parent".
I want each "instance" of a "source" on each level to connect to one of its parents. It's not important which ones connect but all need to be connected and to different parents.
The final results should look something like this:
SOURCE TARGET Level ID P_ID
0 1 1 1 NULL
0 2 1 2 NULL
2 3 2 3 2
2 4 2 4 2
2 5 2 5 2
1 3 2 6 1
1 4 2 7 1
1 5 2 8 1
5 3 3 9 5
5 3 3 10 8
4 3 3 11 4
4 3 3 12 7
3 6 3 13 3
3 6 3 14 6
3 6 4 15 9
3 6 4 16 10
3 6 4 17 11
3 6 4 18 12
Any suggestions on how to write a good ms-sql query for this?
Link to sample data and SQL Fiddle
The query to use is below.
;with cte as (
select *,rn=row_number() over (partition by level, target
order by id),
lc=count(1) over (partition by level, target)
from tbl
)
select a.*, b.id as parent_id
from cte a
left join cte b on b.level=a.level-1
and b.target=a.source
and b.rn=(a.rn-1)%b.lc+1
order by id
Items are sequenced at each level/target combination
Children are linked to parents using by sequence, however if there are more children than parents, the MOD (%) operator takes care of going back to the first parent and continues distribution

Oracle : select maximum value from different columns of the same row

The whole question is pretty much in the title. For each row of the table I'd like to select the maximum of a subset of columns.
For example, from this table
name m1 m2 m3 m4
A 1 2 3 4
B 6 3 4 5
C 1 5 2 1
the result would be
name max
A 4
B 6
C 5
The query must be compatible oracle 8i.
Given this test data ...
SQL> select *
2 from your_table
3 /
NAME M1 M2 M3 M4
---- ---------- ---------- ---------- ----------
A 1 2 3 4
B 6 3 4 5
C 1 5 2 1
SQL>
... a straightforward GREATEST() call will give the desired result:
SQL> select name
2 , greatest(m1, m2, m3, m4) as the greatest_m
3 from your_table
4 /
NAME THE_GREATEST_M
---- --------------
A 4
B 6
C 5
SQL>
Note that greatest() will return NULL if any of the arguments are null. If this is a problem then use nvl() to provide a default value which won't distort the outcome. For instance, if no values can be negative....
SQL> select name
2 , greatest(nvl(m1,0), nvl(m2,0), nvl(m3,0), nvl(m4,0)) as the greatest_m
3 from your_table
4 /
NAME THE_GREATEST_M
---- --------------
A 4
B 6
C 5
SQL>
Use GREATEST but also handle possible NULL's
SELECT name, GREATEST(NVL(m1,0), NVL(m2,0), NVL(m3,0), NVL(m4,0)) AS "Max"
FROM yourtable
Input:
name m1 m2 m3 m4
A 1 2 3 4
B 6 3 4 5
C 1 5 2 1
Output:
NAME Max
A 4
B 6
C 5
SQL Fiddle: http://sqlfiddle.com/#!4/ae268/7/0
Input:
name m1 m2 m3 m4
A 1 2 3 null
B 6 null 4 5
C 1 5 2 1
Output:
NAME Max
A 3
B 6
C 5
SQL Fiddle: http://sqlfiddle.com/#!4/b1c46/1/0