Copy Sql Server Graph database with data - sql

I am having a simple SQL Graph Database.
Database:
CREATE TABLE Person (
ID INTEGER PRIMARY KEY,
name VARCHAR(100)
) AS NODE;
CREATE TABLE City (
ID INTEGER PRIMARY KEY,
name VARCHAR(100)
) AS NODE;
CREATE TABLE Travels AS EDGE;
INSERT INTO Person VALUES (3,'Cecil');
INSERT INTO Person VALUES (4,'Diane');
INSERT INTO Person VALUES (2,'Bob');
INSERT INTO Person VALUES (1,'Alice');
Insert into City VALUES (1, 'Almaty')
Insert into City VALUES (2, 'Bangkok')
Insert into City VALUES (3, 'Casablanca')
Insert into City VALUES (4, 'Dublin')
INSERT INTO Travels VALUES ((SELECT $node_id FROM Person WHERE ID = 1),
(SELECT $node_id FROM City WHERE ID = 1));
INSERT INTO Travels VALUES ((SELECT $node_id FROM Person WHERE ID = 2),
(SELECT $node_id FROM City WHERE ID = 2));
INSERT INTO Travels VALUES ((SELECT $node_id FROM Person WHERE ID = 3),
(SELECT $node_id FROM City WHERE ID = 3));
INSERT INTO Travels VALUES ((SELECT $node_id FROM Person WHERE ID = 4),
(SELECT $node_id FROM City WHERE ID = 4));
I would like to copy these tables to a different tables. My goal is to make it within C#, but simple TSQL solution would be good enough.
CREATE TABLE Person2 (
ID INTEGER PRIMARY KEY,
name VARCHAR(100)
) AS NODE;
CREATE TABLE City2 (
ID INTEGER PRIMARY KEY,
name VARCHAR(100)
) AS NODE;
CREATE TABLE Travels2 AS EDGE;
I can copy data from Node tables easily, if i would read only user data and not an internal column $node_id:
insert into Person2(ID, name) (select Id, name from Person)
insert into City2(ID, name) (select id, name from City)
but in table Travels, I am having just this information:
select $edge_id, $from_id, $to_id from Travels :
{"type":"edge","schema":"dbo","table":"Travels","id":0} {"type":"node","schema":"dbo","table":"Person","id":3} {"type":"node","schema":"dbo","table":"City","id":0}
and in order to copy this, i would need to create a join over tables Person, City, Travels to get original IDS and then join it with Person2 and City2 to get new values $from_id, $to_id for Travels2
Another option would be to use functions Graph_ID_FROM_NODE_ID and NODE_ID_FROM_PARTS:
insert into Person2($node_id, ID, name)
(select ''+NODE_ID_FROM_PARTS(OBJECT_ID('dbo.Person2'),Graph_ID_FROM_NODE_ID($node_id)), Id, name from Person )
insert into City2($node_id, ID, name)
(select ''+NODE_ID_FROM_PARTS(OBJECT_ID('dbo.City2'),Graph_ID_FROM_NODE_ID($node_id)), Id, name from City )
Insert into Travels2 ($edge_id, $from_id, $to_id)
(select ''+EDGE_ID_FROM_PARTS(OBJECT_ID('dbo.Travels2'), Graph_ID_FROM_EDGE_ID($edge_id)), ''+NODE_ID_FROM_PARTS(OBJECT_ID('dbo.Person2'),Graph_ID_FROM_NODE_ID($from_id)), ''+NODE_ID_FROM_PARTS(OBJECT_ID('dbo.City2'),Graph_ID_FROM_NODE_ID($to_id)) from Travels
)
Probably, i don't need to copy ids of edges, so last insert would be a bit easier, but i wonder, if there is not any easier way how to copy graph tables.

Related

Rename column after PIVOT

I am newbie in SQL so apologize if the question does not make sense.
I have a table that looks like (I am on google colab)
CREATE TEMP TABLE test (
name STRING,
subjectId INT,
score INT
);
INSERT INTO test (name, subjectId, score) VALUES ('David', 123, 90);
INSERT INTO test (name, subjectId, score) VALUES ('David', 10, 80);
INSERT INTO test (name, subjectId, score) VALUES ('Ana', 34, 75);
INSERT INTO test (name, subjectId, score) VALUES ('Ryan', 123, 100);
There is a column called subjectId. I would like to apply the PIVOT operator on. I do not know what are the distinct values in this column. So I first create a string to record the distinct value of this column:
DECLARE subjects STRING;
SET subjects = (
SELECT
CONCAT('(', STRING_AGG(DISTINCT CAST(subjectId AS STRING), ', '), ')'),
FROM
test
);
Now I can proceed to apply the PIVOT operation:
EXECUTE IMMEDIATE format("""
SELECT
*
FROM (
SELECT name, subjectId, score FROM test
) AS T
PIVOT
(
max(score) for subjectId in %s
) AS P
""", subjects);
This give me the following table:
Now you can see the columns are named according to the distinct values of the subjectId column. What I would like to do is to rename those columns to something like subject1, subject2, subject3, etc., and I do not care about the order. How can I do that?

How to handle Multivalue attribute in sql server

I have a table in Data warehouse.
Create table customer
(
id int,
name varchar(30),
address varchar(50)
);
let data in table
insert into Customer values(1, 'Smith', 'abc,def, lkj');
insert into Customer values(2, 'James', 'pqr,lmn');
i want to split the table address column and insert new row if we have many values. Like
1 Smith abc
1 Smith def
1 Smith lkj
2 James pqr
2 James lmn
i have data of 100000 recrds, please help me in this regards.
You can use string_split() and adjust the insert statement:
insert into Customer (id, name, address)
select v.id, v.name, s.value
from (values (1, 'Smith', 'abc,def,lkj')
) v(id, name, address) cross apply
string_split(v.address, ',') s;
You might also want to add a check constraint on address so it does not contain a comma.
You would load from a staging table to the final table by doing:
insert into Customer (id, name, address)
select t.id, t.name, s.value
from staging t cross apply
string_split(v.address, ',') s;

I need to migrate data from one old table to a new table by storing appropriate CityId instead CityName

I'm migrating data from one table to another table in SQL Server, In this process what I need to do is "I have 10 columns in old table one column is 'CityName' which is varchar and in the new table, I have a column 'CityId' which is an integer. And I have other table which has data about city id and names. I need store the appropriate cityId in new table instead of CityName. Please help me. Thanks in advance.
You'll need to join the source table to the CityName field in the city information table:
INSERT INTO dbo.Destination (CityID, OtherStuff)
SELECT t1.CityID, t2.OtherStuff
FROM CityInformationTable t1
INNER JOIN SourceTable t2
ON t1.CityName = t2.CityName
Below should give you an idea, you need to inner join to your look up table to achieve this.
declare #t_cities table (Id int, City nvarchar(20))
insert into #t_cities
(Id, City)
values
(1, 'London'),
(2, 'Dublin'),
(3, 'Paris'),
(4, 'Berlin')
declare #t table (City nvarchar(20), SomeColumn nvarchar(10))
insert into #t
values
('London', 'AaaLon'),
('Paris', 'BeePar'),
('Berlin', 'CeeBer'),
('London', 'DeeLon'),
('Dublin', 'EeeDub')
declare #finalTable table (Id int, SomeColumn nvarchar(10))
insert into #finalTable
select c.Id, t.SomeColumn
from #t t
join #t_cities c on c.City = t.City
select * from #finalTable
Output:
Id SomeColumn
1 AaaLon
3 BeePar
4 CeeBer
1 DeeLon
2 EeeDub

Sql query select all messages from everybody inside every group where this one user is at

I'm trying to get all of the messages, from EVERY user, from 2 groups, where the user is located. But I don't know how to get all message from every group. This is my code so far:
SELECT DISTINCT m.*
FROM `message` m
INNER JOIN users u
ON u.id = m.idUser
LEFT JOIN whats_app w
ON w.idUser= u.id
WHERE u.id = w.idUser
So there is ONLY ONE user in 2 groups. I wan't to get all messages from everybody inside the groups where the ONE user is located at.
this is some simple sql query als example:
create table users (
id int PRIMARY KEY NOT NULL,
name varchar(60)
);
create table whatsapp(
idUser ,
idGroup int
);
create table allGroups(
id int PRIMARY KEY NOT NULL,
name varchar(60)
);
create table message_send(
id int,
idUser int,
message text
);
INSERT INTO users(id, name) VALUES
(1, 'John'),
(2, 'Martijn'),
(3, 'Rick'),
(4, 'Vera'),
(5, 'Leon');
INSERT INTO allGroups(id, name) VALUES
(1, 'School'),
(2, 'Friends'),
(3, 'moreFriends'),
(4, 'secretmeeting');
INSERT INTO message_send(id, idUser, message) VALUES
(1, 2, 'How are you feeling today?'),
(2, 1, 'What up?'),
(3, 4, 'I am fine, you?'),
(4, 1, 'hi!');
create table message_send(
id int,
idUser int,
idGroup int,
message text
);
Create message table like this and then just directly join with user and group you will get the output there is not need for the table watsapp
select b.name,message
from
message_send as a,
users as b
where
a.idUser=b.id
Similarly join the group table

sql update query

I want to strip off all _ prefixes in the name column, but the result may cause a conflict. So if the result duplicates with existing ones, I want to suffix a _ to it until there's no duplication.
In the below example case, _test should be renamed to test___.
create table A
(
name VARCHAR2(20) unique,
id int
);
insert into a (name, id) values ('_test', 1);
insert into a (name, id) values ('test', 2);
insert into a (name, id) values ('test_', 3);
insert into a (name, id) values ('test__', 4);
Try this:
merge into A
using (with aa as (select id, trim('_' from name) name from A)
select rpad(name,
length(name) - 1 + row_number()
over(partition by name order by id),
'_') name2,
id
from AA) s
on (s.id = a.id)
when matched then
update set a.name = s.name2