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

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

Related

Multi column exist statement

I am trying to insert data to a table from another where data is not already exists
The table I am inserting the data into
CREATE TABLE #T(Name VARCHAR(10),Unit INT, Id INT)
INSERT INTO #T
VALUES('AAA',10,100),('AAB',11,102),('AAC',12,130)
The table I am selecting the data from
CREATE TABLE #T1(Name VARCHAR(10),TypeId INT,Unit INT, Id INT)
INSERT INTO #T1
VALUES('AAA',3,10,100),('AAA',3,10,106)
In this case I want to select ('AAA',3,10,106) from #T1 because AAA,106 combination not exists in #T
Basically what I want is to populate unique Name and Id combination
I tried below which doesn't seems to work
SELECT *
FROM #T1
WHERE NOT EXISTS(SELECT * FROM #T)
You have to somehow correlate the two tables:
SELECT *
FROM #T1
WHERE NOT EXISTS(SELECT *
FROM #T
WHERE #T1.Name = #T.Name AND #T1.ID = #T.ID)
The above query essentially says: get me those records of table #T1 which do not have a related record in #T having the same Name and ID values.
Your best bet is probably to use a insert statement with a subquery. Something like this:
SQL Insert Into w/Subquery - Checking If Not Exists
Edit: If you're still stuck, try this--
INSERT INTO #T (Name, Unit, Id)
SELECT Name, Unit, Id
FROM #T1
WHERE
NOT EXISTS (SELECT Name, Unit, Id FROM #T
WHERE #T.Name = #T1.Name AND #T.Unit = #T1.Unit AND #T.Id = #T1.Id)

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

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;

Is it possible to join on columns with datatype Text or ntext?

Is it possible to join on columns with datatype Text or ntext?
NO (without an explicit conversion).
From BOL
Comparison operators test whether two expressions are the same.
Comparison operators can be used on all expressions except expressions
of the text, ntext, or image data types.
This code
create table #t1 (t text)
create table #t2 (t text)
insert into #t1 values ('1')
insert into #t1 values ('2')
insert into #t1 values ('3')
insert into #t2 values ('1')
insert into #t2 values ('2')
select *
from #t1 t1
join #t2 t2 ON t1.t=t2.t
----this works
--select *
--from #t1 t1
-- join #t2 t2 ON cast(t1.t as varchar(max))=cast(t2.t as varchar(max))
drop table #t1
drop table #t2
gives the error:
The data types text and text are incompatible in the equal to operator.

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