Sql Server Nested Inserts possible - sql-server

I have data in flatfile structure which I need to Insert into two tables. The structure is:
ID FName SName DOB Response1 Description1 Response2 Description2 Response3 Description3
3 Bill John 01/01 Yes Fault NULL NULL NULL NULL
4 Cat Bill 01/01 Yes FaultX Emer FaultYX Zeber Nuhgt
The two tables where the above data will be inserted:
Persons table -> ID, FName, SName, DOB
PersonsRelations table -> ID, Response, Description where Response1, 2 etc is NOT NULL.
I have started the tsql query but not sure how to complete/achieve this. The query should read row after row and foreach create a new row in Persons table and insert the related responses & descriptions as new rows in PersonsRelations table. So for example for record with ID = 4 there will be 3 related new row entries in PersonsRelations table.

This should do the trick, you can use the APPLY operator to unpivot a table.
create table #tobeinserted
(
ID int,
FName varchar(50),
SName varchar(50),
DOB date,
Response1 varchar(50),
Description1 varchar(50),
Response2 varchar(50),
Description2 varchar(50),
Response3 varchar(50),
Description3 varchar(50)
);
create table #persons
(
ID int,
FName varchar(50),
SName varchar(50),
DOB date
);
create table #personsRelations
(
PersonId int,
Response varchar(50),
Description varchar(50)
);
insert into #tobeinserted (ID,FName,SName,DOB,Response1,Description1,Response2,Description2,Response3,Description3)
values (3,'Bill','John','20140101','Yes','Fault',NULL,NULL,NULL,NULL),
(4,'Cat','Bill','20140101','Yes','FaultX','Emer','FaultYX','Zeber','Nuhgt');
insert into #persons (id,fname,sname,dob)
select id+6000000, fname, sname, dob
from #tobeinserted
insert into #personsRelations (PersonId, Response, Description)
select t.id+6000000, a.response, a.description
from #tobeinserted t
cross apply
(
values(Response1,Description1),(Response2,Description2),(Response3,Description3)
) as a(response, description)
where a.response is not null
select * from #persons;
select * from #personsRelations;
drop table #personsRelations;
drop table #persons;
drop table #tobeinserted;

Related

How to delete the multiple columns from the SQL table in SQlite3?

My database contains 'n' number of columns:
name Phone_no Person_1 Person_2 Person_3 Person_4
john 123 1 2 3 4
Nolan 1234 23 34 1 5
If the Phone_no is 1234 then I want to delete the columns Person_1, Person_3.
I know about the column numbers(Column 3( Person_1), Column 5( Person_3 )) which has to be deleted.
Is there any way to delete the multiple columns through a single SQL statement.
Is this what you want?
update mytable set person_1 = null, person_5 = null
where phone_no = 1234
I understand that by delete columns person_1 and person_3 where phone_no is 1234 you mean set values to null in columns person_1 and person_3 where phone_no is 1234.
If you want to actually remove the columns, then it's a different question. In SQLite, you need to recreate the table:
create table tmp_table(
name varchar(50), -- adapt the datatypes and lengths to your requirement
phone_no int,
person_2 varchar(50),
person_4 varchar(50)
);
insert into tmp select name, phone, person_2, person_4 from mytable;
drop table mytable;
create table mytable(
name varchar(50),
phone_no int,
person_2 varchar(50),
person_4 varchar(50)
);
insert into mytable select name, phone, person_2, person_4 from tmp_table;
drop table tmp_table;
Is there any way to delete the multiple columns through a single SQL statement.
Another way is to run a single SQLite3 statement multiple times:
https://stackoverflow.com/a/16162224/3426192
e.g: SQLite 2021-03-12 (3.35.0) now supports: DROP COLUMN

How to create Invoice

SELECT
dbo.PaymentMaster.Code,
dbo.PaymentMaster.OrderNo,
dbo.PaymentMaster.CustIssueNo,
dbo.PaymentMaster.Amount,
dbo.CustomerMaster.CustName,
dbo.OrderRequestMaster.ORequestQty,
InvoiceMaster.SGST,
InvoiceMaster.CGST,
InvoiceMaster.SGST,
InvoiceMaster.SubTotal,
InvoiceMaster.TotalAmount
FROM
dbo.CustomerIssueMaster,
dbo.PaymentMaster,
dbo.CustomerMaster,
dbo.OrderMaster,
dbo.OrderRequestMaster,
InvoiceMaster
WHERE (dbo.PaymentMaster.CustIssueNo = dbo.CustomerIssueMaster.CustIssueNo
OR OrderMaster.OrderNo = PaymentMaster.OrderNo)
AND OrderRequestMaster.ORequestNo = OrderMaster.ORequestNo
I want to create invoice where all conditions should be match but I didn't get any row when there is one row which should be given as result.
I got this result from payment master. and I want customer info, order request info , order info and payment info in invoice master with invoice master field i.e Code, InvoiceNo, CustNo, InvoiceDate, SubTotal, CGST, SGST, TotalAmount.
Code PaymentNo OrderNo CustIssueNo PaymentMode PaymentStatus Amount PaymentDate InvoiceNo InvoiceDate
4 KCS[P][00004] NULL KCS[CI][00001] Cash Paid 500 14:28.3 NULL NULL
5 KCS[P][00005] KCS[O][00001] NULL Cash Paid 2000 22:33.9 NULL NULL
6 KCS[P][00006] KCS[O][00002] NULL Cash Paid 2000 40:38.1 NULL NULL
I got this results
Without any data we are going to be very hard pressed to help. You say one row should meet criteria, but it is very hard to see how only one record would be returned unless your tables have only one record!
I note from your query that you want CustName, without including CustomerMaster in your WHERE clause - this will lead to trouble!
Please use the following code in a query window and add any missing fields that are important. Then create some INSERT lines to populate. Re-post this so that we can help you with a query that does what you want:
declare #CustomerIssueMaster table
(
CustIssueNo int
)
declare #PaymentMaster table
(
Code int,
PaymentNo varchar(50),
OrderNo varchar(50),
CustIssueNo varchar(50),
PaymentMode varchar(50),
PaymentStatus varchar(50),
Amount decimal (18,2),
PaymentDate datetime,
InvoiceNo int,
InvoiceDate datetime
)
declare #CustomerMaster table
(
CustName varchar(50)
)
declare #OrderRequestMaster table
(
ORequestQty int,
ORequestNo int
)
declare #InvoiceMaster table
(
SGST decimal(18,2),
CGST decimal(18,2),
SubTotal decimal(18,2),
TotalAmount decimal(18,2)
)
declare #OrderMaster table
(
OrderNo int
)
INSERT INTO #PaymentMaster VALUES(4, 'KCS[P][00004]', NULL, 'KCS[CI][00001]','Cash','Paid',500,'2014-03-28', NULL, NULL)
INSERT INTO #PaymentMaster VALUES(5, 'KCS[P][00005]', 'KCS[O][00001]', NULL, 'Cash','Paid',2000,'2014-03-28', NULL, NULL)
INSERT INTO #PaymentMaster VALUES(6, 'KCS[P][00006]', 'KCS[O][00002]', NULL, 'Cash','Paid',2000,'2014-03-28', NULL, NULL)
SELECT * FROM #PaymentMaster
EDIT
Please note I have amended the structure of #PaymentMaster and given three INSERTs to mimic the data you show from SELECT * FROM PaymentMaster, with one exception: I do not understand what format your PaymentDate is supposed to be. The first two looked like times, but the third cannot be. I just stuck in a dummy date instead.
Now will you please do the same for the other tables? I have shown you the format you need to use.

SQL Server 2008 R2: Delete duplicate rows from multiple tables and keep original one

I have the 5 employee tables as shown below.
---Table: Emp_1
CREATE TABLE Emp_1
(
Emp_ID VARCHAR(10),
Emp_FName VARCHAR(10),
Emp_LName VARCHAR(10),
Emp_PNumber VARCHAR(10)
);
---Table: Emp_2
CREATE TABLE Emp_2
(
Emp_ID VARCHAR(10),
Emp_FName VARCHAR(10),
Emp_LName VARCHAR(10),
Emp_PNumber VARCHAR(10)
);
---Table: Emp_3
CREATE TABLE Emp_3
(
Emp_ID VARCHAR(10),
Emp_FName VARCHAR(10),
Emp_LName VARCHAR(10),
Emp_PNumber VARCHAR(10)
);
---Table: Emp_4
CREATE TABLE Emp_4
(
Emp_ID VARCHAR(10),
Emp_FName VARCHAR(10),
Emp_LName VARCHAR(10),
Emp_PNumber VARCHAR(10)
);
---Table: Emp_5
CREATE TABLE Emp_5
(
Emp_ID VARCHAR(10),
Emp_FName VARCHAR(10),
Emp_LName VARCHAR(10),
Emp_PNumber VARCHAR(10)
);
--Insertion: Emp_1
INSERT INTO Emp_1 VALUES('A1','Abram','Mak','123');
INSERT INTO Emp_1 VALUES('A2','Sam','William','321');
--Insertion: Emp_2
INSERT INTO Emp_2 VALUES('A3','John','Marsh','456');
INSERT INTO Emp_2 VALUES('A4','Tom','Lee','654');
--Insertion: Emp_3
INSERT INTO Emp_3 VALUES('A5','Abram','Mak','789');
INSERT INTO Emp_3 VALUES('A6','Shawn','Meben','987');
--Insertion: Emp_4
INSERT INTO Emp_4 VALUES('A7','Sam','William','189');
INSERT INTO Emp_4 VALUES('A8','Mark','Boucher','287');
--Insertion: Emp_5
INSERT INTO Emp_5 VALUES('A9','Gery','Joy','907');
INSERT INTO Emp_5 VALUES('A10','Anthony','Desosa','977');
Now I will insert the each table name into Container table.
I have the following table called as Container which contains the table names, which may be many in my
case I have just inserted 5 as shown below.
--Table : Container
CREATE TABLE Container
(
TableName VARCHAR(50)
);
--Insertion
INSERT INTO Container VALUES('Emp_1');
INSERT INTO Container VALUES('Emp_2');
INSERT INTO Container VALUES('Emp_3');
INSERT INTO Container VALUES('Emp_4');
INSERT INTO Container VALUES('Emp_5');
Note: Now I want to delete the duplicate row from each table and want to keep the original as it is.
And the condition for delete the duplicate row is:
If the Emp_FName and Emp_LName is match with the other tables then the duplicated row has to be deleted and
original row keep as it is.
In my example the Emp_FName and Emp_LName : 'Abram','Mak' repeated in the table Emp_3 which has to be deleted and original
one which is present in the table Emp_1 has keep as it is.
And Emp_FName and Emp_LName : 'Sam','William' repeated in the table Emp_4 which has to be deleted and original
one which is present in the table Emp_1 has keep as it is.
For single Table: For single table I can use the following script to delete the duplicate one and keep the original one.
;WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY Emp_FName,Emp_LName ORDER BY Emp_FName) Row_Number FROM Emp_1
)
DELETE FROM CTE
WHERE Row_Number > 1;
My question is how to delete duplicate row from the multiple tables which are dynamic I mean in my Container table the tables
may be more than 5 also.
This query will delete it (emp1 > emp2 ... > emp5):
Declare #sql nvarchar(max) = ''
Select #sql = coalesce(#sql, '')+ '
Delete d From ['+c2.TableName+'] as d
Inner join ['+c1.TableName+'] as c on c.Emp_FName = d.Emp_FName and c.Emp_LName = d.Emp_LName;
'
From Container as c1
Inner Join Container as c2 On c2.TableName > c1.TableName
Order By c1.TableName, c2.TableName
Print #sql
EXEC sp_executesql #sql
However, I think you should take some time to think about your system and data model and try to find a better way of doing it without using dynamic queries.

Transform row in column in a table

I am trying to rotate the visualization of a table showing the lines as columns without any kind of aggregation.
Suppose I have this table
create table user
id int,
name nvarchar(100),
company nvarchar(100),
division nvarchar(100),
city nvarchar(100)
that can be retrieved with this select
select name,company division, city from user order by id
wich gives me this result
john Company1 division1 City1
Peter Company2 division2 City2
Mary Company3 division3 City3
.
.
but what I need is to show each line as a column and the first column with the name of the field like this
Name john Peter Mary ....
Company Company1 Company2 Company3 ....
Division division1 division2 division3 ....
City City1 City2 City3 ....
How can I accomplish this? I Tried using this unpivot
select col,value
from
(select cast(name as varchar) as name,
cast(Company as varchar) as company,
cast(Division as varchar) as division
cast(City as varchar) as city
from user) p
unpivot
(value for col in (name,company,division,city)) as unpvt
but this is what I got (Note: I want all the names in the same row)
name john
Company Company1
Division division1
City City1
name peter // this should be in the first row as a second column
Company Company2
Division division2
City City2
...
This is super ugly, but it's the only way I could figure out how to do what you want solely in SQL Server. If you copy and paste the code it should run and give you results and leave your database clean. I use a couple permanent tables to work around some dynamic sql scoping limitations, but I drop them both before it's done.
If Object_ID('tempdb..#userInfo') Is Not Null Drop Table #userInfo
Create Table #userInfo (id Int, name Varchar(100), company Varchar(100), division Varchar(100), city Varchar(100))
Insert #userInfo (id, name, company, division, city)
Values (1, 'john','company1', 'division1', 'city1'),
(2, 'peter','company2', 'division2', 'city2'),
(3, 'mary','company3', 'division3', 'city3'),
(4, 'timmy','company4', 'division4', 'city4'),
(5, 'nancy','company5', 'division5', 'city5'),
(6, 'james','company6', 'division6', 'city6'),
(7, 'brandon','company7', 'division7', 'city7'),
(8, 'jay','company8', 'division8', 'city8')
If Object_ID('tempdb..#unPivoted') Is Not Null Drop Table #unPivoted
Create Table #unPivoted (id Int, rid Int, col Varchar(100), value Varchar(100))
Insert #unPivoted
Select id, Row_Number() Over (Partition By id Order By value) As rID, col, value
From #userInfo p
Unpivot (value For col In (name, company, division, city)) As u
If Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput
Select 1 As OrderCol,'City' As ColName Into dbo.TempQueryOutput
Union
Select 2,'Company'
Union
Select 3,'Division'
Union
Select 4,'Name'
Declare #sql Nvarchar(Max),
#maxID Int,
#loopIter Int = 1
Select #maxID = Max(id)
From #userInfo
While #loopIter <= #maxID
Begin
Set #sql = 'Select o.*, u.value As Col' + Convert(Nvarchar(100),#loopIter) + ' Into dbo.TempQueryTable
From dbo.TempQueryOutput o
Join #unPivoted u
On o.OrderCol = u.rid
And u.id = ' + Convert(Nvarchar(100),#loopIter)
Exec sp_executeSQL #sql
If Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput
Select * Into dbo.TempQueryOutput
From dbo.TempQueryTable
If Object_ID('dbo.TempQueryTable') Is Not Null Drop Table dbo.TempQueryTable
Set #loopIter = #loopIter + 1
End
Update dbo.TempQueryOutput
Set OrderCol = Case
When ColName = 'Name' Then 1
When ColName = 'Company' Then 2
When ColName = 'Division' Then 3
When ColName = 'City' Then 4
End
Select *
From dbo.TempQueryOutput
Order By OrderCol
If Object_ID('dbo.TempQueryOutput') Is Not Null Drop Table dbo.TempQueryOutput

Select row data as ColumnName and Value

I have a history table and I need to select the values from this table in ColumnName, ColumnValue form. I am using SQL Server 2008 and I wasn’t sure if I could use the PIVOT function to accomplish this. Below is a simplified example of what I need to accomplish:
This is what I have:
The table’s schema is
CREATE TABLE TABLE1 (ID INT PRIMARY KEY, NAME VARCHAR(50))
The “history” table’s schema is
CREATE TABLE TABLE1_HISTORY(
ID INT,
NAME VARCHAR(50),
TYPE VARCHAR(50),
TRANSACTION_ID VARCHAR(50))
Here is the data from TABLE1_HISTORY
ID NAME TYPE TRANSACTION_ID
1 Joe INSERT a
1 Bill UPDATE b
1 Bill DELETE c
I need to extract the data from TABLE1_HISTORY into this format:
TransactionId Type ColumnName ColumnValue
a INSERT ID 1
a INSERT NAME Joe
b UPDATE ID 1
b UPDATE NAME Bill
c DELETE ID 1
c DELETE NAME Bill
Other than upgrading to Enterprise Edition and leveraging the built in change tracking functionality, what is your suggestion for accomplishing this task?
You could try using a UNION
Test Data
DECLARE #TABLE1_HISTORY TABLE (
ID INT,
NAME VARCHAR(50),
TYPE VARCHAR(50),
TRANSACTION_ID VARCHAR(50))
INSERT INTO #TABLE1_HISTORY
SELECT 1, 'Joe', 'INSERT', 'a'
UNION ALL SELECT 1, 'Bill', 'UPDATE', 'b'
UNION ALL SELECT 1, 'Bill', 'DELETE', 'c'
SQL Statement
SELECT [TransactionID] = Transaction_ID
, [Type] = [Type]
, [ColumnName] = 'ID'
, [ColumnValue] = CAST(ID AS VARCHAR(50))
FROM #Table1_History
UNION ALL
SELECT [TransactionID] = Transaction_ID
, [Type] = [Type]
, [ColumnName] = 'NAME'
, [ColumnValue] = [Name]
FROM #Table1_History
ORDER BY TransactionID
, ColumnName
This can be done with the UNPIVOT function in SQL Server:
select transaction_id,
type,
ColumnName,
ColumnValue
from
(
select transaction_id,
type,
cast(id as varchar(50)) id,
name
from TABLE1_HISTORY
) src
unpivot
(
ColumnValue
for ColumnName in (ID, Name)
) un

Resources