How can I join on a stored procedure?
I actually like the previous answer (don't use the SP), but if you're tied to the SP itself for some reason, you could use it to populate a temp table, and then join on the temp table. Note that you're going to cost yourself some additional overhead there, but it's the only way I can think of to use the actual stored proc.
Again, you may be better off in-lining the query from the SP into the original query.
How to Execute a Stored Procedure in a Join Statement SQL Server
Use a scalar function instead.
CREATE FUNCTION GETID
(
@id int
)
RETURNS int
AS
BEGIN
return (select top 1 id from test1 where testid=@id)
END
Or, review methods in post: Get top 1 row of each group
Use cross apply (or outer apply), which executes once on right side of query.
Or, use row_number() over partition to rank the group rows and select based on rank.
declare @test table (id int, name varchar(100))
insert into @test (id, name) values (1, 'abc')
insert into @test (id, name) values (1, 'te')
declare @test1 table (id int, testid int, name varchar(100))
insert into @test1 (id, testid, name) values (1, 1, 'xxx')
insert into @test1 (id, testid, name) values (2, 1, 'yyy')
insert into @test1 (id, testid, name) values (3, 1, 'zzz')
insert into @test1 (id, testid, name) values (4, 2, 'aaa')
Select * from @test t
cross apply (select top 1 * from @test1
where testid = t.id
order by id) -- change group order as needed
as t1
Can we make join between two stored procedures in SQL Server
You can put result sets from both SP into temp tables and then join them:
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
--Here you add all columns from SP output with there datatypes
)
Then you can:
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
The same way for second SP, then join:
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid
Don't forget to DROP temp tables:
DROP TABLE #PackageAccept
DROP TABLE #PackageProgress
The full batch will be like:
IF OBJECT_ID(N'#PackageAccept') IS NOT NULL
BEGIN
DROP TABLE #PackageAccept
END
ELSE
BEGIN
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
)
END
IF OBJECT_ID(N'#PackageProgress') IS NOT NULL
BEGIN
DROP TABLE #PackageProgress
END
ELSE
BEGIN
CREATE TABLE #P (
PackageId INT,
packagenumber INT,
[Total] INT,
Accept INT,
Remain INT
--etc
)
END
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
INSERT INTO #PackageProgress
EXEC [dbo].[TestPackageProgress]
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid
How to make a join with the stored procedure result?
The answer is that you should use an 'iterator function' in the FROM clause:
FROM TABLE(FUNCTION stored_procedure(arg1, arg2)) AS alias(col1, col2, ....)
The 'alias' is not always necessary, but look hard at the column names in the output of executing the procedure directly:
EXECUTE stored_procedure(arg1, arg2)
If that contains unique column names, you'll be OK; if not, you won't and you'll need the AS alias(col1, col2, ...)
notation.
Here's an analogue (more or less) to your query.
Trivial function that could be written differently, but works:
CREATE FUNCTION SimpleElements(lo INTEGER, hi INTEGER) RETURNING INTEGER AS Atomic_Number;
DEFINE an INTEGER;
FOREACH SELECT Atomic_Number
INTO an
FROM Elements
WHERE Atomic_Number BETWEEN lo AND hi
ORDER BY Atomic_Number
RETURN an WITH RESUME;
END FOREACH;
END FUNCTION;
Query using TABLE(FUNCTION stored_procedure(arg1, arg2))
:
The MOD function is used as simple way of generating some groups to count, but it illustrates the notation which is the main point of the exercise.
SELECT COUNT(*) AS group_count, MOD(b.atomic_number, 3) AS mod_num
FROM TABLE(FUNCTION SimpleElements(1, 10)) AS a(Atomic_Number)
JOIN Elements AS b
ON a.atomic_number = b.atomic_number
GROUP BY mod_num
ORDER BY mod_num;
Output:
3 0
4 1
3 2
Table of Elements
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL UNIQUE CONSTRAINT c1_elements
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
name CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
atomic_weight DECIMAL(8,4) NOT NULL,
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
INSERT INTO elements VALUES( 1, 'H', 'Hydrogen', 1.0079, 'Y');
INSERT INTO elements VALUES( 2, 'He', 'Helium', 4.0026, 'Y');
INSERT INTO elements VALUES( 3, 'Li', 'Lithium', 6.9410, 'Y');
INSERT INTO elements VALUES( 4, 'Be', 'Beryllium', 9.0122, 'Y');
INSERT INTO elements VALUES( 5, 'B', 'Boron', 10.8110, 'Y');
INSERT INTO elements VALUES( 6, 'C', 'Carbon', 12.0110, 'Y');
INSERT INTO elements VALUES( 7, 'N', 'Nitrogen', 14.0070, 'Y');
INSERT INTO elements VALUES( 8, 'O', 'Oxygen', 15.9990, 'Y');
INSERT INTO elements VALUES( 9, 'F', 'Fluorine', 18.9980, 'Y');
INSERT INTO elements VALUES( 10, 'Ne', 'Neon', 20.1800, 'Y');
INSERT INTO elements VALUES( 11, 'Na', 'Sodium', 22.9900, 'Y');
INSERT INTO elements VALUES( 12, 'Mg', 'Magnesium', 24.3050, 'Y');
INSERT INTO elements VALUES( 13, 'Al', 'Aluminium', 26.9820, 'Y');
INSERT INTO elements VALUES( 14, 'Si', 'Silicon', 28.0860, 'Y');
INSERT INTO elements VALUES( 15, 'P', 'Phosphorus', 30.9740, 'Y');
INSERT INTO elements VALUES( 16, 'S', 'Sulphur', 32.0650, 'Y');
INSERT INTO elements VALUES( 17, 'Cl', 'Chlorine', 35.4530, 'Y');
INSERT INTO elements VALUES( 18, 'Ar', 'Argon', 39.9480, 'Y');
…
Conditional Join in SQL Server stored procedure
The left join
is fine. But you can also use exists
:
Select u.*
from users u
where (u.filter1 = 1 and
exists (select 1 from filtertable1 ft where u.filtercount1 = ft.filtercount1)
) or
(u.filter2 = 1 and
exists (select 1 from filtertable2 ft where u.filtercount2 = ft.filtercount1)
) or
(u.filter3 = 1 and
exists (select 1 from filtertable3 ft where u.filtercount3 = ft.filtercount1)
) ;
Note: I'm not sure if you want and
or or
between the conditions. With and
the logic would be slightly different.
Inner Join in stored procedure
You need to define reference for you UnitsTbl. Think of these references as new objects of same class, in terms of OOP. Also, it is a good habit to use references for whenever querying over a table.
SELECT *
FROM
ItemsMainTbl t1
INNER JOIN
UnitsTbl u1 ON t1.FirstUnit = u1.UnitID
INNER JOIN
UnitsTbl u2 ON t1.SecondUnit = u2.UnitID
INNER JOIN
UnitsTbl u3 ON t1.ThirdUnit = u3.UnitID
stored procedure ( inner join from same table)
Consider using a row-limiting query:
create proc precipitacao_maxima_data
@data date
as
select top (1) t.*
from weather_station.precipitacao t
where data_observacao = @data
order by valor_observacao desc;
This simply selects all rows whose data_observacao
matches the given @data
parameter, sorts them by descending valor_observacao
, and retains the first row only.
Related Topics
Saving Results with Headers in SQL Server Management Studio
Changing Precision of Numeric Column in Oracle
How to Query for Null Values in JSON Field Type Postgresql
Return Only One Row from the Right-Most Table for Every Row in the Left-Most Table
Turn Off SQL Logging While Keeping Settings.Debug
Best Way to Compare Dates Without Time in SQL Server
SQL Count* Group by Bigger Than,
Adding an One-Out-Of-Two Not Null Constraint in Postgresql
How Much Does Wrapping Inserts in a Transaction Help Performance on SQL Server
Difference Between Different Types of SQL
Convert Integer to Text in SQLite's Select Query
Cross Apply VS Outer Apply Speed Difference
Postgresql Not Ilike Clause Does Not Include Null String Values