Insert values from one table to another having different primary key - sql

I have 2 tables. Tab A and Tab B
Tab A
Id Name
2 John
3 Peter
4 Rachel
I need to insert records in table B to get following:
Tab B
PrId ID Resident Date.
1 2 Yes 7/1/2018
2 3 Yes 7/1/2018
3 4 Yes 7/1/2018
PrId is the primary key of table B, Id comes from Table A and rest of the values are hard coded.
Please suggest the script to do the same

Are you looking to simply do a straight-forward insert from one table into another? If so, here's an example you can run in SSMS:
-- create table variables for illustration purposes --
DECLARE #tableA TABLE ( [Id] INT, [Name] VARCHAR(10) );
DECLARE #tableB TABLE ( [PrId] INT IDENTITY (1, 1), [Id] INT, [Resident] VARCHAR(10), [Date] SMALLDATETIME );
-- insert sample data into #tableA --
INSERT INTO #tableA ( [Id], [Name] ) VALUES ( 2, 'John' ), ( 3, 'Peter' ), ( 4, 'Rachel' );
-- show rows in #tableA --
SELECT * FROM #tableA;
/*
+----+--------+
| Id | Name |
+----+--------+
| 2 | John |
| 3 | Peter |
| 4 | Rachel |
+----+--------+
*/
-- insert records from #tableA to #tableB --
INSERT INTO #tableB (
[Id], [Resident], [Date]
)
SELECT
[Id], 'Yes', '07/01/2018'
FROM #tableA;
-- show inserted rows in #tableB --
SELECT * FROM #tableB;
/*
+------+----+----------+---------------------+
| PrId | Id | Resident | Date |
+------+----+----------+---------------------+
| 1 | 2 | Yes | 2018-07-01 00:00:00 |
| 2 | 3 | Yes | 2018-07-01 00:00:00 |
| 3 | 4 | Yes | 2018-07-01 00:00:00 |
+------+----+----------+---------------------+
*/

If you have your tables set up with a Primary Key and Foreign Key then you can run the following select query to join the two tables into one.
select a.PrId, b.ID, a.Resident, a.Date
from Table a inner join
Table b on a.PrID = b.ID
look up inner joins here https://www.w3schools.com/sql/sql_join_inner.asp
and foreign key https://www.w3schools.com/sql/sql_foreignkey.asp
In the future please do some research before posting

Related

SQL Server - SQL query to convert 0 or 1 or 2 rows into a single row with 2 columns

I have a schema as below
Test
--------------------
| Id | Name |
--------------------
| 1 | A001 |
| 2 | B001 |
| 3 | C001 |
--------------------
RelatedTest
---------------------------------
| Id | Name | TestId |
---------------------------------
| 1 | Jack | NULL |
| 2 | Joe | 2 |
| 3 | Jane | 3 |
| 4 | Julia | 3 |
---------------------------------
To briefly explain this schema RelatedTest has a nullable FK to Test and the FKId can appear either 0 or 1 or 2 times but never more than 2 times.
I am after a t-SQL query that reports the data in Test in the following format
TestReport
---------------------------------------------------------------------------
| TestId | TestName | RelatedTestName1 | RelatedTestName2 |
---------------------------------------------------------------------------
| 1 | A001 | NULL | NULL |
| 2 | B001 | Joe | NULL |
| 3 | C001 | Jane | Julia |
I can safely assume that TestReport will not need any more than two columns for RelatedTestName.
The schema is beyond my control and I am just looking to query it for some reporting.
I've been trying to utilise the Pivot function but I'm not entirely sure how I can use it so that RelatedTestName1 and RelatedTestName1 can be NULL in the case where there is no RelatedTest records. And also since RelatedTestName is a varchar I'm not sure how to apply an appropriate aggregate if that's what is needed.
Preparing Data:
DROP TABLE IF EXISTS Test
GO
CREATE TABLE Test (Id INT PRIMARY KEY, Name VARCHAR(10)) ON [PRIMARY]
GO
INSERT INTO Test Values
(1, 'A001')
,(2, 'B001')
,(3, 'C001')
GO
DROP TABLE IF EXISTS RelatedTest
GO
CREATE TABLE RelatedTest (
Id INT,
Name VARCHAR(10),
TestId INT FOREIGN KEY REFERENCES Test (Id)
) ON [PRIMARY]
GO
INSERT INTO RelatedTest Values
(1, 'Jack', NULL)
,(2, 'Joe', 2)
,(3, 'Jane', 3)
,(3, 'Julia', 3)
GO
Query:
;WITH CTE AS
(
SELECT TestId = T.Id
,TestName = T.Name
,RelatedTestName = RT.Name
,RN = ROW_NUMBER() OVER(PARTITION BY T.Id ORDER BY RT.Id ASC)
FROM Test T
LEFT JOIN RelatedTest RT
ON T.Id = RT.TestId
)
SELECT DISTINCT
C.TestId
,C.TestName
,RelatedTestName1 = (SELECT RelatedTestName FROM CTE A WHERE A.TestId = C.TestId AND A.RN = 1)
,RelatedTestName2 = (SELECT RelatedTestName FROM CTE A WHERE A.TestId = C.TestId AND A.RN = 2)
FROM CTE C;

Insert on a child table and update FK on parent

I have a parent table with the following structure and data:
---------------------------------------------
| Id | TranslationId | Name |
---------------------------------------------
| 1 | NULL | Image1.jpg |
| 2 | NULL | Image7.jpg |
| 3 | NULL | Picture_Test.png |
---------------------------------------------
And the empty child table which holds the translated images:
-------------------------------------------------------------------------
| Id | De | Fr | En |
-------------------------------------------------------------------------
| | | | |
-------------------------------------------------------------------------
Now I'm looking for a single query statement or at least few queries which I can run without any further programming. Doing this job with scripting or programming would be easy but I have often situations where I need this kind of insert / update. And developing each time a small console app is not feasible.
At the end the two tables should look like this:
---------------------------------------------
| Id | TranslationId | Name |
---------------------------------------------
| 1 | 28 | NULL |
| 2 | 29 | NULL |
| 3 | 30 | NULL |
---------------------------------------------
-------------------------------------------------------------------------
| Id | De | Fr | En |
-------------------------------------------------------------------------
| 28 | Image1.jpg | NULL | NULL |
| 29 | Image7.jpg | NULL | NULL |
| 30 | Picture_Test.png | NULL | NULL |
-------------------------------------------------------------------------
Thank you for any advice.
You could do it something like the below :
INSERT INTO Child
(
Id
,De
,Fr
,En
)
OUTPUT Inserted.Id INTO #Temp
SELECT Id
,De
,Fr
,En
FROM #Values --If you are using a table type to insert into the Child table as a set based approach
;WITH CTE
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Rnk
,Id
FROM #Temp
)
,CTE1 AS
(
SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Rnk
,*
FROM Parent
)
UPDATE cte1
SET TranslationId = cte.Id
FROM CTE1 cte1
JOIN CTE cte ON cte.Rnk = cte1.Rnk
Demo, assuming Name is unique in the first table
create table tab1 (
id int identity
,TranslationId int null
,Name nvarchar(max) null
);
insert tab1 (Name)
values
('Image1.jpg')
,('Image7.jpg')
,('Picture_Test.png')
,(null)
create table tab2 (
id int identity (100,1)
,De nvarchar(max) null
,Fr nvarchar(max) null
,En nvarchar(max) null
);
-- Update them
declare #map table(
name nvarchar(max)
,ref int
);
insert tab2 (de)
output inserted.De, inserted.id
into #map(Name, ref)
select Name
from tab1 src
where Name is not null and not exists (select 1 from tab2 t2 where t2.De = src.Name);
update t1 set TranslationId = ref, Name = null
from tab1 t1
join #map m on t1.Name = m.Name;
select * from tab1;
select * from tab2;
I figured out in the meantime how to do it. Applied on the database, the query looks like this:
DECLARE #Temp TABLE (ImageId INT, Id INT)
MERGE INTO Translation USING
(
SELECT Image.Name AS Name, Image.Id AS ImageId
FROM Candidate
INNER JOIN Candidacy ON Candidate.Id = Candidacy.CandidateId
INNER JOIN Election ON Candidacy.ElectionId = Election.Id
INNER JOIN SmartVoteCandidate ON Candidate.Id = SmartVoteCandidate.CandidateId
INNER JOIN Image ON SmartVoteCandidate.SpiderImageId = Image.Id
WHERE Election.Id = 1575) AS temp ON 1 = 0
WHEN NOT MATCHED THEN
INSERT (De)
VALUES (temp.Name)
OUTPUT temp.ImageId, INSERTED.Id
INTO #Temp (ImageId, Id);
UPDATE Image
SET Image.TranslationId = t.Id, Name = NULL
FROM #Temp t
WHERE Image.Id = t.ImageId
The solution is heavily inspired by
Is it possible to for SQL Output clause to return a column not being inserted?
Using a join in a merge statement

sql query select combined select from multiple table

I really don't know what the title should be, but here the question
I have 2 table (actually more)
table a table b
id (pk)| country id(fk)| Branch
------ | ------ ------|--------
01 | Indonesia 01 | Jakarta
01 | Bali
if i do select * from a,b where a.id=b.id
the result will be
id | Country |Branch
01 | Indonesia|Jakarta
01 | Indonesia|Bali
I want the result to be like below
id | Country | Branch
01 | Indonesia | Jakarta,Bali
Is it possible?
I dont really trying to do research(i mean searching) as I don't know what keyword should I search
When using MySQL, GROUP_CONCAT is the function you're looking for.
Set up the tables like in the request above:
create table a (
`id` int(15) auto_increment primary key,
`country` varchar(200)
);
create table b (
`id` int(15) not null,
`branch` varchar(200),
foreign key(`id`) references a(`id`)
);
insert into a values (1, 'Indonesia');
insert into b values (1, 'Jakarta');
insert into b values (1, 'Bali');
Perform the query:
select a.id,
a.country,
group_concat(distinct b.branch) as 'branch'
from a
left join b on a.id=b.id;
Output:
| id | country | branch |
|----|-----------|--------------|
| 1 | Indonesia | Jakarta,Bali |

SQL - How do I add the same Scope_Identity() value in two tables in the same stored procedure, provided I'm adding data into them in the form of TVP?

I have the following tables -
CREATE TABLE Entity
(
EntityId INT IDENTITY(1,1) PRIMARY KEY,
EntityName NVARCHAR(20),
EntityShortName NVARCHAR(5),
EntityDescription NVARCHAR(100)
)
CREATE TABLE EntityAttributes
(
EntityId INT FOREIGN KEY REFERENCES Queues(EntityId),
AttributeType INT,
AttributeValue NVARCHAR(20)
)
And the following TVPs that I'm making use of to add values into these tables -
CREATE TYPE TVP_Entity AS TABLE
(
EntityName NVARCHAR(20),
EntityShortName NVARCHAR(5),
EntityDescription NVARCHAR(100)
)
CREATE TYPE TVP_EntityAttributes AS TABLE
(
AttributeType INT,
AttributeValue NVARCHAR(20)
)
An entity would be defined with Name, ShortName, Description in the first table and other attributes which will be stored in the second table (in EAV form).
I want to write a stored procedure with which I can add multiple entities in a single execution using the TVPs defined above. How can I accomplish this? I'm stuck at the point where I'm unable to use SCOPE_IDENTITY() to add values to the second table as I'm inserting multiple entities.
Try this by adding the EntityName to the TVP_EntityAttributes type. Full example:
SQL Fiddle
MS SQL Server 2008 Schema Setup:
CREATE TABLE Entity
(
EntityId INT IDENTITY(1,1) PRIMARY KEY,
EntityName NVARCHAR(20) UNIQUE,
EntityShortName NVARCHAR(5),
EntityDescription NVARCHAR(100)
)
CREATE TABLE EntityAttributes
(
EntityId INT FOREIGN KEY REFERENCES Entity(EntityId),
AttributeType INT,
AttributeValue NVARCHAR(20)
)
CREATE TYPE TVP_Entity AS TABLE
(
EntityName NVARCHAR(20),
EntityShortName NVARCHAR(5),
EntityDescription NVARCHAR(100)
)
CREATE TYPE TVP_EntityAttributes AS TABLE
(
EntityName NVARCHAR(20),
AttributeType INT,
AttributeValue NVARCHAR(20)
)
GO
Now add your stored procedure:
CREATE PROCEDURE AddEntity
(
#entities TVP_Entity READONLY,
#attributes TVP_EntityAttributes READONLY
)
AS
INSERT INTO Entity(EntityName, EntityShortName, EntityDescription)
SELECT [EntityName], [EntityShortName], [EntityDescription]
FROM #entities
INSERT INTO EntityAttributes([EntityId],[AttributeType],[AttributeValue])
SELECT E.EntityId, A.[AttributeType], A.[AttributeValue]
FROM Entity E
INNER JOIN #attributes A
ON E.EntityName = A.EntityName
Query 1:
DECLARE #entities TVP_Entity
DECLARE #attributes TVP_EntityAttributes
INSERT INTO #entities(EntityName, EntityShortName, EntityDescription)
SELECT 'Entity1', 'E1', 'Entity One'
UNION
SELECT 'Entity2', 'E2', 'Entity Two'
UNION
SELECT 'Entity3', 'E3', 'Entity Three'
INSERT INTO #Attributes( EntityName,AttributeType,AttributeValue)
SELECT 'Entity1', 1, 2
UNION
SELECT 'Entity1', 2, 3
UNION
SELECT 'Entity2', 3, 2
UNION
SELECT 'Entity2', 4, 3
UNION
SELECT 'Entity3', 5, 4
UNION
SELECT 'Entity3', 6, 4
UNION
SELECT 'Entity3', 7, 21
UNION
SELECT 'Entity3', 8, 32
EXEC AddEntity #entities , #attributes
SELECT *
FROM Entity E
INNER JOIN EntityAttributes EA
ON E.EntityId = EA.EntityId
Results:
| EntityId | EntityName | EntityShortName | EntityDescription | EntityId | AttributeType | AttributeValue |
|----------|------------|-----------------|-------------------|----------|---------------|----------------|
| 1 | Entity1 | E1 | Entity One | 1 | 1 | 2 |
| 1 | Entity1 | E1 | Entity One | 1 | 2 | 3 |
| 2 | Entity2 | E2 | Entity Two | 2 | 3 | 2 |
| 2 | Entity2 | E2 | Entity Two | 2 | 4 | 3 |
| 3 | Entity3 | E3 | Entity Three | 3 | 5 | 4 |
| 3 | Entity3 | E3 | Entity Three | 3 | 6 | 4 |
| 3 | Entity3 | E3 | Entity Three | 3 | 7 | 21 |
| 3 | Entity3 | E3 | Entity Three | 3 | 8 | 32 |

I want generate XML file in a hierarchical form

I have a table like this (Actually it contains more 6000 records)
IdIndustry | IndustryCode | IndustryName | ParentId
---------------------------------
1 | IND | Industry | NULL
2 | PHARM | Pharmacy | 1
3 | FIN | Finance | NULL
4 | CFIN | Corporate | 3
5 | CMRKT | Capital M | 4
DDL:
CREATE TABLE [dbo].[tblIndustryCodes](
[IdIndustry] [int] IDENTITY(1,1) NOT NULL,
[IndustryCode] [nvarchar](5) NULL,
[IndustryName] [nvarchar](50) NULL,
[ParentId] [int] NULL,
CONSTRAINT [PK_tblIndustryCodes] PRIMARY KEY CLUSTERED ([IdIndustry] ASC)
Inserts:
INSERT INTO [tblIndustryCodes]
([IndustryCode]
,[IndustryName]
,[ParentId])
VALUES
('IND','Industry',NULL),
('PHARM','Pharmacy',1),
('FIN','Finance',NULL),
('CFIN','Corporate Finance',3),
('CMRKT','Capital Markets',4)
And i want to generate a XML file like this(Simplified tree like structure)
<IND>
<PHARM>
</PHARM>
</IND>
<FIN>
<CFIN>
<CMRKT>
</CMRKT>
</CFIN>
<FIN>
I don't want to use recursion as it would downgrade the performance dramatically as this table has more than 60000 records in table.
I would be glad if i get the output in same format, since i will be using this output XML to send a request.
And more importantly it will be dynamic in nature.
Try this procedure not much sure about its efficiency as I am creating a temp table to get result
create procedure get_path as begin
DECLARE #cnt INT
DECLARE #n INT
DECLARE #tmpTable TABLE(id int,
indCode varchar(50),
indName varchar(100),
parentId int,
path varchar(500))
insert #tmpTable
select [IdIndustry], [IndustryCode], [IndustryName], [ParentId],
null from tbl
select #cnt = count(*) from #tmpTable where parentId is null
update a set a.path = CONCAT(b.indName,'/',a.indName) from #tmpTable a, #tmpTable b where b.parentid is null and a.parentid = b.id
select #n = count(*) from #tmpTable where path is null
while (#cnt < #n) begin
update a set a.path = concat(b.path, '/', b.indName, '/', a.indName) from #tmpTable a, #tmpTable b where b.path is not null and a.parentid = b.id
select #n = count(*) from #tmpTable where path is null
end
update #tmpTable set path = indName where parentid is null
select * from #tmpTable order by path
end
go
Query 1:
exec get_path
Results:
| ID | INDCODE | INDNAME | PARENTID | PATH |
-------------------------------------------------------------------------------
| 3 | FIN | Finance | (null) | Finance |
| 4 | CFIN | Corporate | 3 | Finance/Corporate |
| 5 | CMRKT | Capital M | 4 | Finance/Corporate/Corporate/Capital M |
| 1 | IND | Industry | (null) | Industry |
| 2 | PHARM | Pharmacy | 1 | Industry/Pharmacy |
Hope this helps.....
SQL FIDDLE