Update the column of table1 and get it on table2 - sql

How can I create a query where I can update the table1 column date that I get it on table2?
Here is some example of the tables
Table1:
| stud_id | start_date | birt_date | name | exam_date |
| s001 | 11/19/2018 | 05/20/1999 | john | 10/20/2018 |
| s003 | 01/01/2018 | 05/25/1995 | mike | 10/20/2018 |
| s005 | 12/23/2018 | 02/20/1999 | ed | 10/20/2018 |
| s005 | 12/23/2018 | 02/20/1999 | ed | 10/05/2017 |
Table2:
| stud_id | start_date | exam_date |
| s005 | 01/01/2017 | 10/20/2018 |
| s001 | 01/01/2017 | 10/20/2018 |
| s003 | 01/01/2017 | 10/20/2018 |
Basically I want to change just the start_date of the 3 so s006 will not change.
How can I accomplish that using query? I was thinking using in then select the table but I think its not gonna work.
I need to based on two or more column for the condition of my update so I want to update the table 1 where table1.stud_id = table2.stud_id and table1.exam_date = table2.exam_date

do join and update
update t1
set t1.stardate=t2.startdate,
t1.exam_date=t2.exam_date
from table1 t1 join table2 t2
on t1.stud_id=t2.stud_id
where t2.stud_id='s003' -- if you just need s003 update

You can also use CTE as well to update:
;With cte as
(
select t1.start_date as t1date,t2.start_date as t2date from table1 t1
join table2 t2
on t1.stud_id=t2.stud_id
and t1.exam_date=t2.exam_date
)
update cte set t1date=t2date

You can join the 2 tables:
UPDATE T1
SET Start_Date = T2.Start_Date
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.stud_id = T2.stud_id
AND T1.exam_date = T2.exam_date

Related

Join on the first id where the date is the same or in the past

How can I join Table1 on Table2 on opid, only if the table1's date <= table2's date, AND it has no other matches?
Here are some example tables:
Table1
------------+-------+-----+
date | spend | opid|
------------+-------+-----+
2019-07-05 | 5 | 1 |
------------+-------+-----+
2019-07-07 | 4 | 2 |
------------+-------+-----+
2019-07-08 | 6 | 2 |
------------+-------+-----+
Table2
+------------+-------+-----+
| date | users | opid|
+------------+-------+-----+
| 2019-07-06 | 100 | 1 |
+------------+-------+-----+
| 2019-07-08 | 200 | 2 |
+------------+-------+-----+
Expected Table
+------------+-------+-------+
| date | spend | users |
+------------+-------+-------+
| 2019-07-05 | 10 | 100 |
+------------+-------+-------+
| 2019-07-07 | 4 | null |
+------------+-------+-------+
| 2019-07-08 | 6 | 200 |
+------------+-------+-------+
So 7-July doesn't join, because 8-July has already joined.
I think you should try with inner join.
select t1.id, t1.date, t1.spend, t2.id as table2_id, t2.users
from table1 t1 inner join
table2 t2
on t1.date <= t2.date;
This answers the original version of the question.
I think you want a full join:
select t1.id, t1.date, t1.spend, t2.id as table2_id, t2.users
from table1 t1 full join
table2 t2
on t1.date = t2.date;

How can I subtract two row's values within same column using sql query in access?

(query access)
This is the table structure:
+-----+--------+--------+
| id | name | sub1 |
+-----+--------+--------+
| 1 | ABC | 6.27% |
| 2 | ABC | 7.47% |
| 3 | PQR | 3.39% |
| 4 | PQR | 2.21% |
+-----+--------+--------+
I want to subtract Sub1
Output should be:
+-----+--------+---------+------------------------------------+
| id | name | sub1 | |
+-----+--------+---------+------------------------------------+
| 1 | ABC | 6.27% | 0 First Rec no need Subtract |
| 2 | ABC | 7.47% | 1.2% <=(7.47-6.27) |
| 3 | PQR | 3.39% | 0 First Rec no need Subtract |
| 4 | PQR | 2.21% | -1.18% <=(2.21-3.39) |
+-----+--------+---------+------------------------------------+
Thank you so much.
If you can guarantee consecutive id values, then the following presents an alternative:
select t.*, nz(t.sub1-u.sub1,0) as sub2
from YourTable t left join YourTable u on t.name = u.name and t.id = u.id+1
Change YourTable to the name of your table.
This is painful, but you can do:
select t.*,
(select top 1 t2.sub1
from t as t2
where t2.name = t.name and t2.id < t.id
order by t2.id desc
) as prev_sub1
from t;
This gives the previous value or NULL for the first row. You can just use - for the subtraction.
An index on (name, id) would help a bit with performance. However, if you can upgrade to a better database, you can then just use lag().

Select max value record from one-to-many join

I want to join two tables, but the second table contains multiple rows of parameters on which I wish to build by join.
TABLE1
+------------+-----------+
| Ddate | ROOMNO |
+------------+-----------+
| 2018-22-11 | 101 |
| 2018-22-11 | 102 |
| 2018-22-11 | 103 |
| 2018-22-11 | 104 |
+------------+-----------+
TABLE2 (Multiple rows per Room No)
+------------+-----------+------------------+
| Ddate | ROOMNO | MaxVoltage |
+------------+-----------+------------------+
| 2018-22-11 | 101 | 230 |
| 2018-22-11 | 101 | 240 |
| 2018-22-11 | 101 | 250 -----MAX |
| 2018-22-11 | 102 | 230 |
| 2018-22-11 | 102 | 255 -----MAX |
+------------+-----------+------------------+
DESIRED RESULT (I want the Max Voltage for the Room on the Ddate)
+------------+-----------+------------+
| Ddate | ROOMNO | MaxVoltage |
+------------+-----------+------------+
| 2018-22-11 | 101 | 250 |
| 2018-22-11 | 102 | 255 |
| 2018-22-11 | 103 | 235 |
| 2018-22-11 | 104 | 238 |
| 2018-22-11 | 105 | 255 |
+------------+-----------+------------+
SELECT t2.d, t2.roomno, max(t2.maxvolt)
FROM table1 AS t1 JOIN table2 AS t2 ON t1.ddate = t2.ddate
AND t1.roomno = t2.roomno
GROUP BY t2.d, t2.roomno;
use subquery
select t1.dDate,t1.roomno,mvoltage from table1 t1 join
(select Ddate ,roomno,max(MaxVoltage ) as mvoltage from table2
group by Ddate,roomno
) t2 on t1.Ddate=t2.Ddate
Use apply:
select t1.*, t2.maxvoltage
from table1 t1 outer apply
(select top (1) t2.*
from table2 t2
where t2.roomno = t1.roomno and t2.ddate = t1.ddate
order by maxvoltage desc
) t2;
select t1.dDate,t1.roomno, mvoltage from table1 t1 join
(select Ddate ,roomno,max(MaxVoltage ) as mvoltage from table2
group by Ddate,roomno
) t2 on t1.Ddate=t2.Ddate and t1.Roomno = t2.RoomNo
First you will join between two tables in a regular way, using the date and room no.
then use the aggregate function max for the voltage field with over clause , then group by Room No and Date like following
select distinct t1.Ddate, t1.RoomNo, MAX(t2.MaxVoltage) over(partition by t1.RoomNo order by t1.Ddate) MaxVoltage
from Table1 t1
join Table2 t2 on t2.Ddate = t1.Ddate and t2.RoomNo = t1.RoomNo

SQL query join- unrelated tables

Can someone help me to join the two tables without any primary or secondary keys. Sample table is
TABLE 1
| ID | NAME |
| 1 | x |
| 2 | Y |
| 3 | z |
TABLE 2
| Num | NAME | DATE |
| 52 | X | 12-aug-17 |
| 53 | X | 11-apr-17 |
| 62 | X | 10-aug-11 |
| 12 | y | 2-jan-16 |
| 23 | Y | 3-apr-18 |
I want retrieve data from X
select *
from table2
where name = 'x';
| Num | NAME | DATE |
| 52 | X | 12-aug-17 |
| 53 | X | 11-apr-17 |
| 62 | X | 10-aug-11 |
Now I will get three data from table2. I'm little stuck after this step. I want to get top of data the from table 2 and combine with table one.
I want final output should be
| ID | NAME | Num | DATE |
| 1 | x | 52 | 12-aug-17 |
Can someone suggest me how can I join this table? Its easy to join when we have any primary key but here not the case
Thanks
You can use this:
SELECT TOP(1) table1.ID, table2.Num, table2.Name, table2.DATE
FROM table2 INNER JOIN table1 ON table1.NAME = table2.NAME
WHERE table2.NAME = 'x'
ORDER BY table2.DATE ASC
OR
SELECT table1.ID, table2.Num, table2.Name, table2.DATE
FROM table1 INNER JOIN
(SELECT TOP(1) * FROM table2 WHERE NAME = 'x' ORDER BY DATE ASC) table2
ON table1.NAME = table2.NAME
You need to get the maximum DATE using a subquery, as in:
select t1.id, t2.*
from table1 t1
join table2 t2 on t2.name = t1.name
where t2.date = (
select max(date) from table2 where name = 'x'
);

How can I write a select statement for this use case?

Please help me compose a SELECT statement. I have these two tables:
Table1 Table2
---------------- ------------------------------------------------
ID | PName | | ID | NameID | DateActive | HoursActive |
---------------- ------------------------------------------------
1 | Neil | | 1 | 1 | 8/2/2013 | 3 |
2 | Mark | | 2 | 1 | 8/3/2013 | 4 |
3 | Onin | | 3 | 2 | 8/2/2013 | 2 |
---------------- | 4 | 2 | 8/6/2013 | 5 |
| 5 | 3 | 8/7/2013 | 1 |
| 6 | 3 | 8/8/2013 | 10 |
------------------------------------------------
And I just want to retrieve the earliest DateActive but no duplicate PName. Like this:
PName | DateActive | HoursActive |
----------------------------------------
Neil | 8/2/2013 | 3 |
Mark | 8/2/2013 | 2 |
Onin | 8/7/2013 | 1 |
----------------------------------------
Something like this might do it. You need to find the min date for each NameID first, then join back to the table to get the hours.
SELECT
PName, MaxDate as DataActive, HoursActive
From
Table1 t1
inner Join Table2 t2 on t1.ID = t2.NameID
Inner Join (Select min(DateActive) as mindate, NameID from Table2 Group by NameID) as t3 on t3.mindate = t2.ActiveDate and t3.NameID = t2.NameId
This should be a pretty standard solution:
select t.pname,
t2.dateactive,
t2.hoursac
from table1 t
join table2 t2 on t.id = t2.nameid
join (
select nameid, min(dateactive) mindateactive
from table2
group by nameid
) t3 on t2.nameid = t3.name
and t3.mindateactive = t2.dateactive
If you are using an RDBMS that supports partition by statements, then this would be more efficient:
select pname, dateactive, HoursActive
from (
select t.pname,
t2.dateactive,
t2.hoursactive,
rank() over (partition by t.id order by t2.dateactive) rownum
from table1 t
join table2 t2 on t.id = t2.nameid
) t
where rownum = 1