Hello i have problem i have table
CREATE TABLE doctor(
idDoc SERIAL PRIMARY KEY,
meds TEXT[]
);
I want to store only unique values if my user enter same meds inside
Table before user insert
id
meds
1
{Nalfon,Ocufen,Actron}
After user insert (insert is Actron,Soma,Robaxin) i want update and have in table old values and new values ( Actron is same)
if I UPDATE table with new values I will get
UPDATE doctor SET meds='{Actron,Soma,Robaxin}') WHERE id=1;
id
meds
1
{Actron,Soma,Robaxin}
But i want
id
meds
1
{Nalfon,Ocufen,Actron,Soma,Robaxin}
I don't know how to check if new value is same like value in table and only insert/update table to have unique values.
Given your data structure, you can unnest the existing meds, add in the new ones, and re-aggregate as a unique array:
UPDATE doctor d
SET meds = (select array_agg(distinct med)
from (select med
from unnest('{Actron,Soma,Robaxin}'::text[]) u(med)
union all
select med
from unnest(d.meds) u(med)
) m
)
WHERE idDoc = 1;
Here is a db<>fiddle.
That said, you might consider a junction table with one row per doctor and medicine. That is the more traditional SQL representation for a many-to-many relationship.
I have table like this:
Incident_id is foreign key. What I want to achieve it -> create one more column with named position (int). And populate it like this: find all rows for each incident_id and and update each row with index or list of rows I get by each incident_id. exapmple:
incident_id 5 matches with 4 note rows so updated for the position will be 0, 1, 2, 3 accordingly. Ty
I would not recomment storing such derived information. Instead, you can create a view that uses row_number() to enumerate the rows of each incident_id:
create view myview as
select t.*, row_number() over(partition by incident_id order by id) - 1 rn
from mytable t
To get a stable result, you need a column that can be used to consistently order the rows of each incident: I called it id in the query. You can change that to the relevant column name (or set of columns) for your use case; you would typically use the primary key column(s) of your table.
EDIT
If you really wanted to materialize that value in a new column, and considering that the primary key of your table, you would do:
alter table mytable add column position int;
update mytable t
set position = t1.position
from (
select incident_note_id,
row_number() over(partition by incident_id order by incident_note_id) - 1 position
from mytable
) t1
where t1.incident_note_id = t.incident_note_id;
I have been searching this and can not find the proper answer if I need an JOIN or SUBQUERY, I have tried multiple ways if doing this and honestly I am hitting a major wall. I am trying to do something simple and I don't know how to progress
I have two tables I am trying to use: table 1) data 2) mapping
table 1 is like this the headers are :
Date
Value1
Value2
Value3
Value4
Etc.
Value in CSV style for example would be:
1/1/10,1,2,3,4
1/2/10,5,6,7,8
1/3/10,9,10,11,12
table 2 has only one row though, here are the headers and one row
Value1
Value2
Value3
Value4
The one row would be like:
Description1, Description2, Description3, Description4
So, I want to be able to, for example do a SELECT FROM table 1 and join in the Description for each matching row where the Column names are the same, so sample output based on the above would be to be like this:
1/1/10,1,Description1,2,Description2,3,Description3,4,Description4
1/2/10,5,Description1,6,Description2,7,Description3,8,Description4
Etc
Since there's just one row in table2 and no key, you can simply join it.
select *
from table1
join table2
Since there's just one row in table2 it's questionable why it exists at all. This could be done without a join at all.
select date, value1, 'Description1', value2, 'Description2', value3, 'Description3', value4, 'Description4'
from table1;
There's likely a better way to do this. Having columns like value1, value2, and value3 usually indicates poor table design. Instead of having four value columns, you should have four value rows. And instead of having a table with four columns of descriptions, it should be four rows of descriptions.
For example, let's say you're storing items in an order. An order can have many items. Rather than having a column for each item in an order like item1, item2, item3, you'd have a row for each item in a join table. Below that's order_items. Descriptions of the items is stored separately in its own table, one row per item.
user
----
id bigint primary key
name text not null
items
-----
id bigint primary key
name text not null
orders
------
id bigint primary key
user_id bigint references users(id)
created_at datetime
order_items
-----------
order_id bigint references orders(id)
item_id bigint references items(id)
If you want to look up all the items in an order, with their names, you'd use the order_items table to get all the items in an order, and join with the items table to get each item's name.
select i.name
from order_items oi
join items i on i.id = oi.item_id
where oi.order_id = ?
Comma separated lists of values are awkward to handle.
Rather than a CSV, storing the values in a mapping table is typically used.
If I understand correctly then I believe that the following may demonstrate along the lines of what you want:-
DROP TABLE IF EXISTS table1 /* Assigned Values per date (the mapping table)*/;
DROP TABLE If EXISTS table2 /* Values */;
CREATE TABLE IF NOT EXISTS table2 (valueid INTEGER PRIMARY KEY,value_description TEXT);
CREATE TABLE IF NOT EXISTS table1 (date TEXT, valueid_reference INTEGER REFERENCES table2(valueid),value INTEGER, UNIQUE(date, valueid_reference));
INSERT INTO table2 VALUES (1,'Value1 Description'),(2,'Value2 Description'),(3,'Value3 Description'),(4,'Value4 Description');
INSERT INTO table1 VALUES
('1/1/10',1,1),('1/1/10',2,2),('1/1/10',3,3),('1/1/10',4,4),
('1/2/10',1,5),('1/2/10',2,6),('1/2/10',3,7),('1/2/10',4,8)
;
SELECT date||','||group_concat(value||','||value_description) AS all_values_and_descriptions FROM table1 JOIN table2 ON valueid_reference = valueid GROUP BY date;
SELECT * FROM table1;
This results in :-
Noting that the REFRENCES (Foreign Key) will be a noop unless Foreign Key support is enabled. However, without it will still work.
As can be seen each value per date is an individual row in table 1 (so 4 rows per date). It is the group_concat function that is used to get all the values per date in conjunction with the GROUP BY clause which creates a set of rows (a Group) for each date.
The 2nd SELECT shows the rows in table1 :-
I have a 2 databases that I want to merge with some similiar tables. The source tables have id as bigint and my destination table has int as ID. There aren't that many records in my source table (< 20k) so I want to assign new ids to all records so the ids can fit in an int. How can I do this with sql?
First Option
You can Use Sequence object as follow:
First Create a Sequence object and assign it's Start With value to max Id value in destination table plus 1. For example if max Id in destination table is 100, you need to assign 101 as Start With. You can also obtain the max Id value from destination table using a Max(Id) aggregate function and store it in a variable:
CREATE SEQUENCE SeqId
START WITH [Max value of Id in destination table]
INCREMENT BY 1 ;
GO
Then insert to destination table using following query:
Insert Into tblXXX (Id, ...) Values (NEXT VALUE FOR SeqId, ...)
Read more about Sequence Object
Second Option
You can make the destination table's Id column as Identity column with seed equal to destination table's Id column max value and Increment equal to 1.
Here is detailed example also Here
You did not provide much details so I can only provide a general guideline:
Note: Example assumes that you want to merge tables A and B into C and you want to generate new IDs. I also assume that these IDs are not referenced by other tables (foreign keys).
First you get record counts from tables A and B:
DECLARE #countA INT
DECLARE #countB INT
SET #countA = ( SELECT COUNT(*) FROM A )
SET #countB = ( SELECT COUNT(*) FROM B )
Next you use a window function to generate new IDs and insert records into table C.
INSERT INTO C
SELECT #countA + ROW_NUMBER() OVER( ORDER BY ID ) AS ID, ....
FROM A
INSERT INTO C
SELECT #countA + #countB + ROW_NUMBER() OVER( ORDER BY ID ) AS ID, ....
FROM B
I have two tables.Table A has 4 columns. And table B has two columns.I want to insert value of one column of tabel A from one column of table B based on condtion if id matches.
how i can do this ? For example if [Movieid] in 1st table =[IMDBid] in second table then insert [count] of table 1=[CB] in table 2.
i want to do it once for full table.
[column] -> these are colums
i m using sql server.
Tabel 1 : Movieid,count,
Tabel 2: IMDBid, CB
Results which i want: i want to insert values of CB column in count where Movieid=IMDBid
Tabel 1 :
(Nick Id,MovieId,Rating,MovId)-> (1,4972,6.25,?)(1,24216,7.25,?)
Tabel 2 :
(Imdbid,Title,ImdbPyId,Id)-> (4972,hello,32450,1)(24216,hi,62450,2)
Insert /fill value of MovId(tabel1) using values Id(tabel2)where MovieId(tabel1)==Imdbid(tabel2)
You can do it like,
UPDATE tabl1
SET count = (SELECT CB FROM tabl2 WHERE IMDBid = Movieid)
But it is gonna blow up if you have multiple values returning from the subquery.
So make sure to use the appropriate function to get the single value from that subquery whichever meets your requirements.
If your tables have 1:1 relationship then it should be fine. But if it is 1:n then you need to use either aggragate functions or the TOP 1 clause in that subqyery.
solution is UPDATE tabl1
SET count = (SELECT CB FROM tabl2 WHERE IMDBid = Movieid)