SQL Server Query to get data from multiple tables - sql-server

I need a sql query to get records on the basis of multiple tables. Like below -
There are tables Table_A, Table_B & Table_C. In which Table_A is the main table in which I want to get the data. And Table_B is dependent on Table_A, containing the Foreign Key of Table_A.
Table_A (parent table) ----> Table_B(child table)
And Table_C is contains the Foreign key of table Table_B.
Table_B (parent table) ----> Table_C(child table)
So now I need a data from Table_A and one of the column of Table_C. But that column will contain the comma separate string on the basis of Table_A's primary key value.

So now I need a data from Table_A and one of the column of Table_C.
But that column will contain the comma separate string on the basis of
Table_A's primary key value.
This is the wrong way to solve your abstract problem. If you want multiple items in Table C to be associated with Table A (and based on the comment above Table B has no effect) then you should do the following:
Create a table called CjoinA which has an ID_C and an ID_A a column Then there will be multiple rows for the relations ship so if Table C row ID 1 is related to rows of Table A with IDs 1, 2 and 3 then you would have three rows like this
ID_C ID_A
1 1
1 2
1 3

A possible way would be to create a function which concats the values of table_C:
CREATE FUNCTION [dbo].[GET_TBC](#parentID Integer)
returns nvarchar(MAX)
Begin
declare #result as varchar(MAX)
set #result = ''
select #result = #result + _YOURCOLUMN_ + '; '
from TABLE_C
WHERE PARENT_ID_COL = #parentID
select #result = left (#result , len(#result )-1);
return #result
end
and use this function in your select statement:
SELECT TableA.*, GET_TBC(TableB.ID)
FROM TableA, TableB
WHERE TableB.ParentID = TableA.ID

Related

Copy IDENTITY column from another table and generate new IDs for missing records

I'm trying to copy identity column from one table to another, but I'm getting this error:
Cannot update identity column 'ID'.
I tried following code:
ALTER TABLE [dbo].[TableA]
ADD [ID] INT IDENTITY(20000,1), -- MAX(TableB.Id) < 20000
SET IDENTITY_INSERT TableA ON
UPDATE TableA
SET TableA.[ID] = TableB.[ID]
FROM TableA
INNER JOIN TableB ON TableB.ID = TableA.ID
SET IDENTITY_INSERT TableA OFF;
Scenario
I have two tables with 1:0-1 relationship.
TableA: Code (PK)
A,
B,
C,
D
TableB: Id (PK), Code (Unique)
1, A
2, B
3, D
Question
How to
Create new identity column TableA.Id
Copy values from TableB.Id
Ensure new unique values for TableA.Id if it was missing in TableB.Id
=NOT A REAL ANSWER TO THE ORIGINAL QUESTION, see comment=
You can not update a column which in itself is your join criteria. This just ain't work.
The safest way to keep the identity column intact is to delete rows from Table B in Table A first.
Then just insert from Table B into Table A with IDENTITY_INSERT ON.
Also this assumes there is a 1:1 relationship between the rows common to Table A and Table B. A 1:0-1 relationship between Table A and B means you need to capture ID from Table B in Table A as a foreign key relationship and separate column instead if this can lead to NULL results in Table A.
So in a nutshell (pseudo code) with assumption of 1:1 relationship between the rows:
DELETE FROM Table A WHERE Key EXISTS IN (SELECT Key FROM Table B)
;
SET IDENTITY_INSERT Table A ON
;
INSERT INTO Table A
( id_column, [other_columns [, othercolumns] ] )
SELECT
id_column, [other_columns [, othercolumns] ]
FROM Table B
;
SET IDENTITY_INSERT Table A OFF
;

How to create a table in sql server like other table?

I want to create a table like another table in SQL Server.
In Postgres I used to create it with this request:
CREATE TABLE IF NOT EXISTS table2 (LIKE table1 INCLUDING ALL) INHERITS (table1)
Something like this should work:
IF OBJECT_ID('table1', 'U') IS NULL BEGIN
SELECT TOP 0 * INTO table1 FROM table2
END
This will clone the column definition of table2 in table1 without inserting any data (because of the top 0).
Then you have to create the PK, UK, FK for the table1. For this purpose you can check: https://www.mssqltips.com/sqlservertip/3443/script-all-primary-keys-unique-constraints-and-foreign-keys-in-a-sql-server-database-using-tsql/
With this resource you can generate an ALTER TABLE script to add all PK, UK, FK in a variable and run it like:
DECLARE #sqlCommand nvarchar(1000)
EXECUTE sp_executesql #sqlCommand
SELECT *
INTO table2
FROM table1 where 1=2
SELECT * = select all columns
INTO= place of set
FROM = place to lookup,
WHERE 1=2 = filter criteria
select top 0 * into x from y
will give you an empty shell of a table with no data exactly defined as the original table minus all the indexes , constraints etc

SQL Insert a record and use its Id to update another set of records foreign key

I have 2 tables CombinableOrders and Orders and tempory table of order Ids
Orders contain a nullable FK to CombinableOrders
I create the record as follows
INSERT INTO
CombinableOrders ([Rank])
VALUES (0)
I then need to associate that new combinableOrder with a set of orders derived from a temporary table of ids
UPDATE Orders
SET Orders.CombinableOrder_Id = #Id_To_Original_Insert
FROM Orders AS Orders
INNER JOIN #Ids AS Ids
ON Orders.Id = Ids.Id
How would i get the Id from the new created CombinableOrders?
You probably just want to declare a variable of the right type
DECLARE #id INT
and then set it using SCOPE_IDENTITY() after the insert
SELECT #id = SCOPE_IDENTITY()
Alternatively you could output in the insert using the OUTPUT clause, but that's may be slightly more complicated in your case.

Merge and get Identity on Insert

I need to merge new items in #temp_table into a table_a.
There is also a parent_table, which has a primary key identity column parent_table_id (and table_a has a corresponding foreign-key column for a parent_table_id). Each item in table_a points to a corresponding entry in the parent table.
So for each item in #temp_table, I need to insert into both table_a and parent_table.
The problem is, suppose I merge into the parent_table first, how do I get all of the corresponding parent_table_id items to set in all the table_a inserts? I was thinking of adding a parent_table_id column to #temp_table, initially set to null, then filling it up with values after the merge, but I'm not quite sure how to go about this. There is no other unique column in parent_table that can be used to select the new columns after they are inserted, other than the parent_table_id.
The following is a generic way of doing it (stripped down):
MERGE parent_table AS TARGET
USING #temp_table AS SOURCE
ON
(
TARGET.match_number = SOURCE.match_Number
)
WHEN NOT MATCHED THEN
INSERT
(
item1,
item2,
item3
)
VALUES
(
SOURCE.item1,
SOURCE.item2,
SOURCE.item3,
)
OUTPUT INSERTED.parent_table_id, SOURCE.reference_number INTO #Ids (parent_table_id, reference_number);
Results in #Ids containing all the parent table ids with other important info from the source which can be used elsewhere (i.e. for joining into table_a).

Create new table from Existing table With out identity property to be copied

I am using select * into to create a table from another table and used SET IDENTITY_INSERT ON for newly created table to accept data including identity column.
Now my question is that Is there any way to create a table (say TABLE A) from another existing table (say TABLE B) with out copying identity property of TABLE B to TABLE A.
Of course, let's say TABLEA looks like this:
CREATE TABLE TABLEA (
ID INT PRIMARY KEY IDENTITY(1, 1),
Column1 VARCHAR(50)
)
and let's assume that TABLEB looks the same. If we wanted to move data from TABLEB into TABLEA without moving the identity column we would write this statement:
INSERT INTO TABLEA (Column1)
SELECT Column1 FROM TABLEB
and this will cause every new row in TABLEA to get its own identity value.
But note, you can't issue a SELECT * FROM TABLEB because that would also select the ID column. You have to list out all of the fields you want individually. However, generally speaking, I think a lot of very experienced DBA's and programmers would say that SELECT * FROM Table is really dangerous because if the schema changes everything breaks. You really want to always be specific.
SELECT STUFF((SELECT ', ' + c.name FROM sys.columns c where c.object_id = OBJECT_ID('dbo.TABLE_NAME') and c.is_identity <> 1 FOR XML PATH('')),1, 2, '') AS CSVColumn
This will give you a comma separated list of columns of each table. Copy these statements into notepad to create a script that you can run.

Resources