How to combine two MS SQL Server tables into one in a stored procedure - sql

I have a stored procedure in SQL Server 2008R2 that takes two user defined table types as parameters. Each of these types is a simple table holding an series of Ids:
CREATE TYPE [dbo].[Ids] AS TABLE(
[Id] [int] NULL
)
I want to combine the two parameters passed in to achieve the following result:
DECLARE
#Table1 TABLE (Id INT )
DECLARE
#Table2 TABLE (Id INT )
INSERT INTO #Table1 VALUES (1)
INSERT INTO #Table1 VALUES (2)
INSERT INTO #Table2 VALUES (11)
INSERT INTO #Table2 VALUES (22)
SELECT * FROM #Table1
SELECT * FROM #Table2
DECLARE
#Combined TABLE (T1 INT, T2 INT)
-- TODO: Magically combine the two tables
SELECT * FROM #Combined
-- Output would be the following
1, 11
1, 22
2, 11
2, 22

You seem to want a cross join:
insert into #Combined(t1, t2)
select t1.id, t2.id
from #Table1 t1 cross join
#Table2 t2;

Related

How to join type tables in SQL Server? [duplicate]

This question already has an answer here:
How to fix "Must declare the scalar variable" error when referencing table variable?
(1 answer)
Closed 7 years ago.
Let's say for example I've got the following two types:
CREATE TYPE TBL1 AS TABLE
( id int,
name varchar(max),
status_id int )
GO
CREATE TYPE TBL2 AS TABLE
(
id int,
status varchar(max)
)
GO
These are used with the following piece of SQL
DECLARE #T1 AS TBL1
INSERT INTO #T1 (id, name, status_id)
VALUES (1, 'Test1', 1),
(2, 'Test2', 2)
DECLARE #T2 AS TBL2
INSERT INTO #T2 (id, status)
VALUES (1, 'New'),
(2, 'Old')
Now if I want to use these Types in a query I get an error:
SELECT *
FROM #T1
INNER JOIN #T2 ON #T1.status_id = #T2.id
The error is
Must declare the scalar variable '#T1'
which is strange because I defined the variable as a type.
It seems that you can only use the variable #T1 and #T2 in the FROM-clause. If you give it an alias you can make use of its columns in any other clause.
For example, the following query will work:
SELECT *
FROM #T1 as t1
INNER JOIN #T2 as t2 ON t1.status_id = t2.id

Select query : from clause is having multple tables, but i want where clause to have condition on only two tables

For eg:
SELECT aa.name, aa.id
FROM ba_acct_memo aa, acct_mast bb
WHERE (aa.cod_acct_no=bb.cod_acct_no AND aa.flg_mnt_status='U'
and bb.flg_mnt_status='A')
gives 1 row(for eg)
but
SELECT aa.name, aa.id
FROM ba_acct_memo aa, acct_mast bb, college cc
WHERE (aa.cod_acct_no=bb.cod_acct_no AND aa.flg_mnt_status='U'
and bb.flg_mnt_status='A')
gives same result as in first query but giving it, as many number of rows which are there in college table.
But it should work just as like first query.
Can someone explain the weird behaviour of my query?
Following Steps will help you to understand (Inner) Join.
--Create Table 1 :
Create Table #Table1
(
Roll_No INT ,
Student_Name Varchar(50)
)
Go
--Create Table 2 :
Create Table #Table2
(
Roll_No INT,
Student_Address Varchar(200)
)
Go
--Create Table 3 :
Create Table #Table3
(
Roll_No INT,
Student_Contact_No Varchar(10)
)
Go
-- Insert Values into #Table1:
Insert into #Table1 Values ('1','John')
Insert into #Table1 Values ('2','Alex')
Insert into #Table1 Values ('3','Mike')
Insert into #Table1 Values ('4','Steve')
Insert into #Table1 Values ('5','Jack')
Insert into #Table1 Values ('6','Vicky')
Insert into #Table1 Values ('7','Sid')
Insert into #Table1 Values ('8','Tom')
-- Insert Values into #Table2:
Insert into #Table2 Values ('1','1st Street')
Insert into #Table2 Values ('2','2rd Street')
Insert into #Table2 Values ('3','3rd Street')
Insert into #Table2 Values ('4','4th Street')
Insert into #Table2 Values ('5','5th Street')
Insert into #Table2 Values ('6','6th Street')
Insert into #Table2 Values ('7','7th Street')
Insert into #Table2 Values ('8','8th Street')
-- Insert Values into #Table3:
Insert into #Table3 Values ('1','123-123')
Insert into #Table3 Values ('2','123-111')
Insert into #Table3 Values ('3','123-122')
Insert into #Table3 Values ('4','123-125')
Insert into #Table3 Values ('5','123-126')
Insert into #Table3 Values ('6','123-116')
Insert into #Table3 Values ('7','123-145')
Insert into #Table3 Values ('8','123-132')
--View Data :
Select * from #Table1
Select * from #Table2
Select * from #Table3
-- First Query : (With Out Third Table) :
Select A.Roll_No,A.Student_Name,B.Student_Address from #Table1 A, #Table2 B
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--It will Retrun One Record. If you add third table in this query with out join with any other tables ( Table 1 and Table 2 )
-- Secord Query :
Select A.Roll_No,A.Student_Name,B.Student_Address from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--It will return 8 Same Records. (Because Table 3 having 8 Records)
--You can understand when execute why it is return 8 records.
-- Third Query :
Select * from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--Delete some records from #Table 3 :
Delete #Table3 Where Roll_No > 5
--Execute again Third Query :
-- Third Query :
Select * from #Table1 A, #Table2 B , #Table3 C
Where a.Roll_No = B.Roll_No
and a.Roll_No = 1
--Clean Up:
Drop table #Table1
Drop table #Table2
Drop table #Table3

SQL intersect with other tables, how do I ignore it?

I am trying to run a query given three tables.
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
I Need to get only the values that are present and ignore the null table. This doesn't work since TABLE3 has no values.
SELECT ID
FROM #TABLE1
INTERSECT
SELECT ID
FROM #TABLE2
INTERSECT
SELECT ID
FROM #TABLE3
**Result should be 1**
How do I ignore the any table if it's null but keep the other values?
Why not do a union of select distincts from each table, and then group that by ID and select count(*), and select only rows with count(*) equal to the maximum value of count(*) in the result?
It's a bit of a mess of subqueries at this point unfortunately but you should get the logic :)
Intersect is not going to work for you as you can't add conditions to it.
From what I understand you want to select all records where the ID appears in at least 2 of the tables. I am assuming that the ID is unique to each table.
The following works in MS SQL Server:
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
;WITH AllValues AS
(
SELECT ID
FROM #TABLE1
UNION ALL
SELECT ID
FROM #TABLE2
UNION ALL
SELECT ID
FROM #TABLE3
)
SELECT ID
FROM AllValues
GROUP BY ID
HAVING COUNT(*) > 1
Maybe... But the design of the system is extremely foreign; a real world example would help understand what you're trying to do.
Select count(*), ID FROM (
Select ID from #table1
UNION
Select ID from #table2
UNION
Select ID from #table3) Derived
Where RowNum =1
GROUP BY ID
ORder by count(*) DESC
Updated where clause was in wrong place

Any standard SQL expression to sort results base on IN expression [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
SQL - order by list order
Is there any standard SQL expression to sort results exactly base on IN expression. For example to return the results of the following query so that 2, 4, 6, 8 are returned serially?
SELECT * FROM SOMETABLE WHERE ID IN (2, 4, 6, 8)
The closest thing I can think of is doing a JOIN instead of an IN to a table with the original order with their ordinal rank
SELECT * FROM SOMETABLE INNER JOIN SOMETABLE2 ... etc
ORDER BY SOMETABLE2.original
If you have full controlled over your SQL rendering, then use a CASE expression:
ORDER BY CASE ID
-- render WHEN clauses in the desired order
WHEN 2 THEN 1
WHEN 4 THEN 2
WHEN 6 THEN 3
WHEN 8 THEN 4
END
Assuming you can pass the ids as a fixed delimited string, you can do the following :
-- Populate a number table
DECLARE #Temp Table(Number int)
INSERT INTO #Temp VALUES(1)
INSERT INTO #Temp VALUES(2)
INSERT INTO #Temp VALUES(3)
INSERT INTO #Temp VALUES(4)
INSERT INTO #Temp VALUES(5)
INSERT INTO #Temp VALUES(6)
INSERT INTO #Temp VALUES(7)
INSERT INTO #Temp VALUES(8)
INSERT INTO #Temp VALUES(9)
INSERT INTO #Temp VALUES(10)
SELECT TOP 8000 Number = IDENTITY(int,1,1) INTO [dbo].Numberos FROM #TEMP t1, #TEMP t2, #TEMP t3, #TEMP t4
ALTER TABLE [dbo].[Numbers] ADD CONSTRAINT [PK_Numbers] PRIMARY KEY CLUSTERED ([Number])
-- This function splits a fixed delimited string into a table object
CREATE FUNCTION [dbo].[fixstring_single](#str text, #itemlen tinyint)
RETURNS TABLE
AS
RETURN (SELECT listpos = n.Number,
str = substring(#str, (#itemlen + 1) * (n.Number - 1) + 1, #itemlen)
FROM Numbers n
WHERE n.Number <= (datalength(#str)+1) / (#itemlen+1))
DECLARE #ids varchar(100);
SET #ids = '00002 00001 00004';
-- Join to the number table ordered by the posisiton in the ids string
SELECT * FROM TestT INNER JOIN fixstring_single(#ids, 5) S ON TestT.ID = S.Str ORDER BY S.listpos

How to return table from T-SQL Stored Procedure

SQL Newbie here, and I'm having a hell of a time finding what should be a simple code example to answer what I think is a simple question.
I need to write a stored procedure that does three things in order:
1) Select rows from one table
2) Update rows in another table, using values from the results table in #1
3) Return the results table from #1.
What I can't find is any example about how to return a value like this from a stored procedure. Also, how to retrieve that returned table from the caller (which is another T-SQL script).
Have a look at this.
DECLARE #Table1 TABLE(
ID INT,
VAL int
)
INSERT INTO #Table1 (ID,VAL) SELECT 1, 1
INSERT INTO #Table1 (ID,VAL) SELECT 2, 2
INSERT INTO #Table1 (ID,VAL) SELECT 3, 3
DECLARE #Table2 TABLE(
ID INT,
VAL VARCHAR(MAX)
)
INSERT INTO #Table2 (ID,VAL) SELECT 1, 1
INSERT INTO #Table2 (ID,VAL) SELECT 2, 2
INSERT INTO #Table2 (ID,VAL) SELECT 3, 3
--Lets say this is the 2 tables
--now this will go into the sp
UPDATE #Table1
SET Val = t1.Val + t2.Val
FROM #Table1 t1 INNER JOIN
#Table2 t2 ON t1.ID = t2.ID
SELECT t1.*
FROM #Table1 t1 INNER JOIN
#Table2 t2 ON t1.ID = t2.ID
--and you can insert into a var table in the tsql script that calls the sp
DECLARE #Table1TSQL TABLE(
ID INT,
VAL int
)
INSERT INTO #Table1TSQL (ID,VAL) EXEC YourSP