Keeping track of auto increment columns in a cursor - sql

I wrote a cursor where I needed to copy some rows and insert it into a table with only 1 column different. Say for example I have a table A like this
Id | CID | Country
1 X A
2 X B
3 X C
'Id' in this table is auto increment and primary key and Country is the countries visited by that CID. So when I was asked to update the table where every country visited by CID 'X' has also been visited by CID 'Y'. I wrote a cursor and did an insert into with CID 'Y' and the Country. After I executed my cursor, table A became this:
Id | CID | Country
1 X A
2 X B
3 X C
4 Y A
5 Y B
6 Y C
Now there is another table B that is as follows, where AId is the foreign key referencing Id in A.
AId | AgeOfKids
1 20
1 23
1 28
2 21
2 24
2 29
3 22
3 25
I want to be able to add rows to this table such that it becomes:
AId | AgeOfKids
1 20
1 23
1 28
2 21
2 24
2 29
3 22
3 25
4 20
4 23
4 28
5 21
5 24
5 29
6 22
6 25
To explain in words, the AIds that have the same countries in table A must have the same BeIds in table B. Is it possible to accomplish this? Is so, how can I accomplish this?

Use the OUTPUT clause:
declare #t table (Id int not null,Country char(1) not null)
insert into TableA (CID,Country)
output inserted.id,inserted.Country into #t
select 'Y',Country from TableA where CID = 'X'
And then (should be part of the same batch as the above):
insert into TableB (AId,AgeOfKids)
select t.ID,b.AgeOfKids
from #t t
inner join
TableA a
on
t.Country = a.Country and
a.CID = 'X'
inner join
TableB b
on
a.ID = b.AId
To populate table B.

Related

update _ids values by sorted timestamp with sql

i have a few tables look like below (sqlite)
table a:
a_id (unique)
timestamp
21
123
2
178
33
101
7
221
4
115
table b:
b_id (unique)
a_id
data (no need to sort)
14
4
bb
3
2
dd
22
21
ee
6
7
xx
17
2
tt
11
33
qq
now i want to update these tables' _id according to the timestamp in a as follows:
table a:
a_id
timestamp
1
101
2
115
3
123
4
178
5
221
table b:
b_id
a_id
data
1
1
qq
2
2
bb
3
3
ee
4
4
dd
5
2
tt
6
5
xx
how can i do this easily with sql, without re inserting the data etc?
thanks
i used to create a dummy column with new and sorted ids by timestamp, then update other tables accordingly but it was inefficient and i have forgotten how i did it
update:
to simplify, i want to create a new column sort_id in table a, which holds the value according to the sorted timestamp, so
before:
table a
a_id (unique)
timestamp
21
123
2
178
33
101
7
221
4
115
after:
table a
a_id (unique)
timestamp
sort_id
21
123
3
2
178
4
33
101
1
7
221
5
4
115
2
so how can i fill the sort_id column according to the timestamp?
you want to query your table b data and sort it based on time stamp .
order of rows in a database is not guaranteed at all and it changes anytime after each insert/update, so you need to join two tables and sort based on timestamp column :
select b.*
from table_b b
left join table_a a
on a.a_id = b.a_id
order by a.timestamp
depending on your sqlite version you also can use update from :
update tableb
set sort_id = rn
from (select a_id , row_number() over (order by timestamp) as rn from tableA) tableA
where tableA.a_id = tableB.a_.id
Aftrer you've altered the table to add the new column...
WITH
sorted AS
(
SELECT
a_id,
ROW_NUMBER() OVER (ORDER BY timestamp) AS new_sort_id
FROM
table_a
)
UPDATE
table_a
SET
sort_id = sorted.new_sort_id
FROM
sorted
WHERE
table_a.a_id = sorted.a_id

How to select a value with a column name that also needs selected?

The SQL Server 2005 table I'm working from is really strange. Here's a simplified example:
TABLE 1:
key | a | b | c | d | e | f
z 0 1 2 3 4 5 6
y 1 8 9 10 11 12 13
x 14 15 16 17 18 19 20
w 21 22 23 24 25 26 27
TABLE 2:
id | Value
1 a
2 b
3 c
4 e
5 f
What I need to accomplish is to, in a single statement, select the column name from a different table, then get the value here. So it would be something like "Select (select colName from table2 where id=VAR1) From table1 where key = VAR2"
So table2 will return either a/b/c/d/e/f, and then the main statement will get the value of the corresponding value based on the key.
Table2 will always return a-f, and I will know the VAR1 and VAR2 ahead of time.
You can use UNPIVOT:
SELECT [key], val, col
FROM
(SELECT [key], a, b, c, d, e, f
FROM table1
WHERE [key] = #var2) AS src
UNPIVOT
(val FOR col IN
(a, b, c, d, e, f)
)AS unpvt
WHERE col = (SELECT value FROM table2 WHERE id = #var1)
UNPIVOT operation transposes table data from columns to rows creating an extra field where column name is placed. This way you can query table data using the name of the column that is obtained from table2.
Demo here

SQL copy from one table to another with changing ID value

I have two tables:
A
ID VALUE
----------
1 7
2 5
3 44
4 982
5 1
6 0
7 671
B
ID VALUE
---------------
1 6
2 6
3 77
4 22
How do I copy data from #B to #A to get a different ID (one bigger than the MAX in #A)? For example I need to get
ID VALUE
1 7
2 5
3 44
4 982
5 1
6 0
7 671
8 6
9 6
10 77
11 22
Either make it an IDENTITY column which auto-increments, or this:
INSERT INTO A
SELECT b.ID + (SELECT MAX(ID) FROM A) AS ID, b.Value
FROM B
DEMO
The select is slightly different if the ID in table B has gaps. Then those gaps are transferred.
If the ID column in TableA is not already set to auto-increment, do the following command:
ALTER TABLE TableA MODIFY COLUMN ID INT auto_increment
Now you can just insert all the records from TableB into TableA:
INSERT INTO TableA (VALUE)
SELECT VALUE
FROM TableB
It is not a great idea to rely on the business logic in your query to maintain the order of the ID column. Instead, let SQL take care of it for you; it was designed for this purpose.

How to find distance between two columns in different tables in geom datatype

Update the value in the column "distance" of table 1 by finding the distance between center_geom from table2 and home_location from table 3.
Table 1
obu_id end_location trip_id end_loc_adj distance
1 51 1234
2 57 1357 44
2 63 1351
3 21 1212 20
3 23 4313
Table 2
id obu_id center_geom
int int geom
51 2 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
52 3 "0101000020ED080000AE47E17A35F73341FE65F764723C0841"
57 3 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
21 4 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
Now, see table 1: If we have any value in end_loc_adj then the column : end_loc_adj has to be used rather end_loc Hint: use if-else.
Column name "end_loc" in table 1 has same values as column "id" in table 2.
Table 3
hhid obu_id home_location
(character Int geometry
varying)
11 1 "0101000020ED08000082E2C7A0B2413341BC5818A21F000941"
15 2 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
17 3 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
17 4 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
22 7 "0101000020ED080000AE47E17A35F73341FE65F764723C0841"
I have tried the following:
select ST_Distance_Sphere ( ST_AsText(cast(v.house_location AS text)) , ST_AsText(cast(l.center AS text)))
from public.locations l, clean.vehicles v
where l.obu_id=v.obu_id
and l.obu_id=3
but this works manually for single obu_id
I want to complete it in one go using a function.
Please give me some idea about how to do this.
Thanks.
house_loc:=(select house_location from table1 where obu_id=b.obu_id);
house_loc_geom := ST_Transform(house_loc,4269);
IF b.end_location_adj IS null THEN
end_loc:= (select center from table2 where id=b.end_location and obu_id= b.obu_id);
else
end_loc:= (select center from tabl2 where id = b.end_location_adj and obu_id = b.obu_id);
end if;
center_geom:=ST_Transform(end_loc,4269);
UPDATE table 1 set dist_from_home_in_meter=distance
where obu_id=b.obu_id and trip_id=b.trip_id and end_location=b.end_location;
this is close to answer, need some modifications.

How to combine two tables to get results

The following is my master table:
tablename columnname size order
employee name 25 1
employee sex 25 2
employee contactNumber 50 3
employee salary 25 4
address street 25 5
address country 25 6
And following is my child table:
childid userid masterid isactive size order
1 1 1 Y 25 1
2 1 2 Y 25 2
3 1 3 N 0 0
4 1 4 Y 50 3
I would like to get the table name columnname from master table and size,order form child table against userid when isactive is Y in child table.
Some time, if the value is not there for the particular user than get all the values like tablename, columnname, size, order where isactive isY
I am really sorry to ask this but I am not good at SQL.
Regards.
Use INNER JOIN instead of LEFT JOIN
SELECT rcm.tablename, rcm.columnname, rcc.size, rcc.order
from report_customise_master rcm
INNER JOIN report_customise_child rcc
ON rcm.id = rcc.masterid
WHERE rcm.isactive = 'Y' and rcc.isactive = 'Y'
UPDATE 1
..., COALESCE(rcc.size, rcm.size) as Size,
COALESCE(rcc.`Order`, rcc.`order`) as `Order`