SQL update statement from a history table based on timestamp - sql

I'm trying to write an update statement in Oracle that will find an attribute from a history table based on a timestamp. So, for example the data looks like:
TABLE A
A_ID TIMESTAMP ATTR
---------------------------------
1 5/27/2012 10:30:00 AM ?
TABLE B
B_ID A_ID TIMESTAMP ATTR
---------------------------------------
1 1 5/26/2012 9:01:08 AM W
2 1 5/27/2012 8:38:21 AM X
3 1 5/28/2012 9:01:01 AM Y
4 1 5/29/2012 11:37:54 PM Z
The lower bound is >= B.TIMESTAMP, but I'm not sure how to write the upper bound as < B."the next TIMESTAMP". So, in the example above the attribute on table A should update to "X".
This seems like a fairly common use case. I've seen this post, but it looks like a satisfactory answer was never reached, so I thought I'd post again.

UPDATE A SET attr = (
SELECT b1.attr
FROM B b1
INNER JOIN (
SELECT MAX(b3.timestamp) mx FROM B b3
WHERE b3.timestamp < A.timestamp
) b2 ON b1.timestamp = b2.mx
)
I can't remember if Oracle will allow me to use table A within the inner join sub query... Would you mind trying it?

Related

sum of query result form two different table that have nothing in common

hi i have two query result:
Table A
Id u
1 50,00
2 60,00
3 70,00
and
Table B
id c
4 110,00
5 120,01
6 130,02
Now i have doing two query on this table and i want sum their query result.
I want update column c from table B with 160 that is sum of(110+50).
Table B
Id c
4 160,00
Table B and Table A they have nothing in common.
Now i have doing two query for select their value ed for sum two data:
$data=number_format($row['c']+$row1['u']);
$query_updatee="update B set c= (integer)$data where c=110,00";
Can i sum the data from two different table that don't have nothing in comon?
My output is pg_query(): Query failed: ERRORE: syntax error at or near "1" LINE 1: update B set punti = (integer)1680,00 where c=110,00 ^ in C:\xampp\htdocs\table_A.php on line 81
You can use a subquery to fetch the increment. The rest seems to just be filtering:
update B
set c = c + (select a.u from a where a.id = 1)
where B.id = 4;
Obviously, you can use where b.c = 110.00 if you want to filter by a number (or use a comma if that is how the database is set up).

SQL Update table with all corresponding data from another table concatenated?

Running PostgreSQL 12.4. I am trying to accomplish this but the syntax given there doesn't seem to be working on psql, and I could not find another approach.
I have the following data:
Table 1
ID Trait
1 X
1 Y
1 Z
2 A
2 B
Table 2
ID Traits, Listed
1
2
3
4
I would like to create the following result:
Table 2
ID Traits, Listed
1 X + Y + Z
2 A + B
Concatenating with + would be ideal, as some traits have inherent commas.
Thank you for any help!
Try something like:
update table2
SET traits = agg.t
FROM
(select id,string_agg(trait, ',') t from table1 group by id) agg
where
table2.id = agg.id;
dbfiddle
Concatenating with + would be ideal, as some traits have inherent commas.
You can use whatever delimiter you like (just change the second argument to string_agg).

Oracle query to link records from same table which maps to mapping table

Apologies for the horrible question title,not sure how to articulate it better.
So to start out.
**Table Dummy_Table**
id description filter_key
1 Test Record1 filterkey1
2 Test Record2 filterkey1
3 Test Record1 filterkey2
4 Test Record2 filterkey2
The records with filterkey1 map to a table like this
**Table Mapping_table**
Dummy_Table_id someother_key (one(Dummy_Table_id) to many(someother_key)
1 x
1 y
1 z
1 r
2 y
2 r
Now : In a query I map the id's to each other in the Dummy_Table using the description,so I end up with a resultset like this
id_for_filter_key1 id_for_filterkey2
1 3
2 4
Ok,thats all good and well,it's the next step I'm having a issue with.I need to add records to Table Mapping_table which should end up looking like this
**Table Mapping_table**
Dummy_Table_id someother_key
3 x
3 y
3 z
3 r
4 y
4 r
So in essence whatever the id is for filterKey1 I would like to apply it's someother_key to the id's with filterkey2 (filterKey1 and filterkey2 relate to each other with their descriptions)
Now I don't know if I'm over complicating this.I'll tell you what my problem is.
I have records in the database with filterkey1 which map to the mapping table.Afterwords I added the records with filterkey2.These rows are duplicates just with another filter key.Now I need to apply the same mappings to the records with filterkey2
Changing the table structure is not a option atm.I need to give the DBA a insert query to achieve this.
Many thanks in advance.
This query gives missing values:
SELECT d.id_for_filterkey2, m.someother_key
FROM Mapping_table m
JOIN Dummy_Table d ON m.Dummy_Table_id = d.id_for_filter_key1
Demo: http://sqlfiddle.com/#!4/61ddfe/2
When we have missing values, then we can merge them into Mapping_table:
MERGE INTO Mapping_table m
USING( copy-the-above-query-and-paste-it-here) x
ON (x.id_for_filterkey2 = m.Dummy_Table_id)
WHEN NOT MATCHED THEN
INSERT( Dummy_Table_id, someother_key )
VALUES( x.id_for_filterkey2, x.someother_key );
Demo: http://sqlfiddle.com/#!4/d74304/3

T-SQL: identify difference of x in integer sequence

I have a simple table: here is an example of what the values look like (after taking out confidential values).
What I need to do is count the number of instances the difference between a Date_Nbr value and the one following is greater than 2. I could imagine creating a second table where -- for each Group and Person, an integer count of the number of instances is placed.
Is this even possible in T-SQL? I haven't shown any code, because I'm at a total loss.
For those who need table definitions, it would be this:
Date_Nbr int not null,
Group varchar(5) not null,
Person varchar(5) not null
The values shown would exist within that table (let's call it Date_Seq).
I would be grateful for any ideas. Thank you.
Date_Nbr | Group | Person
1 C A
4 C A
5 C A
8 C A
10 C A
11 C A
13 C A
14 C A
15 C A
P.S. --
I described it verbally above, but this is a visual description of what I hope to achieve, where "Count_Gaps" is the number of times a difference greater than 2 was found in the sequence of "Date_Nbr".
Group | Person | Count_Gaps
C A [integer value]
All records that do not have a corresponding person+group record within 2 higher.
SELECT
*
FROM <table> t1
LEFT join <table> t2 ON t1.group=t2.group AND t1.person=t2.person AND (t1.Date_nbr+1)=t2.Date_nbr
LEFT join <table> t3 ON t1.group=t3.group AND t1.person=t3.person AND (t1.Date_nbr+2)=t3.Date_nbr
WHERE t2.Date_nbr IS NULL
AND t3.Date_nbr IS NULL

Finding contiguous regions in a sorted MS Access query

I am a long time fan of Stack Overflow but I've come across a problem that I haven't found addressed yet and need some expert help.
I have a query that is sorted chronologically with a date-time compound key (unique, never deleted) and several pieces of data. What I want to know is if there is a way to find the start (or end) of a region where a value changes? I.E.
DateTime someVal1 someVal2 someVal3 target
1 3 4 A
1 2 4 A
1 3 4 A
1 2 4 B
1 2 5 B
1 2 5 A
and my query returns rows 1, 4 and 6. It finds the change in col 5 from A to B and then from B back to A? I have tried the find duplicates method and using min and max in the totals property however it gives me the first and last overall instead of the local max and min? Any similar problems?
I didn't see any purpose for the someVal1, someVal2, and someVal3 fields, so I left them out. I used an autonumber as the primary key instead of your date/time field; but this approach should also work with your date/time primary key. This is the data in my version of your table.
pkey_field target
1 A
2 A
3 A
4 B
5 B
6 A
I used a correlated subquery to find the previous pkey_field value for each row.
SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m;
Then put that in a subquery which I joined to another copy of the base table.
SELECT
sub.pkey_field,
sub.target,
sub.prev_pkey_field,
prev.target AS prev_target
FROM
(SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m) AS sub
LEFT JOIN YourTable AS prev
ON sub.prev_pkey_field = prev.pkey_field
WHERE
sub.prev_pkey_field Is Null
OR prev.target <> sub.target;
This is the output from that final query.
pkey_field target prev_pkey_field prev_target
1 A
4 B 3 A
6 A 5 B
Here is a first attempt,
SELECT t1.Row, t1.target
FROM t1 WHERE (((t1.target)<>NZ((SELECT TOP 1 t2.target FROM t1 AS t2 WHERE t2.DateTimeId<t1.DateTimeId ORDER BY t2.DateTimeId DESC),"X")));