简体   繁体   中英

Two SELECT statements in one stored procedure, one supplying input for another and the other returning more than one row

I have a select statement that gets 4 column values in a row for one iteration from a query that has lot of joins. One of the column value has to be given to another select statement as input to check a where condition. This select statement returns three rows for a input from each iteration of the first select statement. I need to get all the column values from the three rows of the second select statement along with the all the column values of the first select statement.

SELECT val1, val2, val3, val4 from ....

SELECT val5, val6 from anotherTable where someColumn = val1

RESULT required :

val1, val2, val3, val4, val51, val61, val52, val62, val53, val63

I, am using two connections and two readers to make this happen, but its slowing me down. I'd like it if I can get this done in a single stored procedure.

You can do something like this

WITH first AS 
(
  SELECT val1, val2, val3, val4
    FROM Table1
   WHERE 1 = 1
), second AS
(
  SELECT val1,
         MIN(CASE WHEN rnum = 1 THEN val5 END) val51,
         MIN(CASE WHEN rnum = 1 THEN val6 END) val61,
         MIN(CASE WHEN rnum = 2 THEN val5 END) val52,
         MIN(CASE WHEN rnum = 2 THEN val6 END) val62,
         MIN(CASE WHEN rnum = 3 THEN val5 END) val53,
         MIN(CASE WHEN rnum = 3 THEN val6 END) val63
    FROM
  (
    SELECT t2.val1, val5, val6, 
           ROW_NUMBER() OVER (PARTITION BY t2.val1 ORDER BY (SELECT 1)) rnum
      FROM Table2 t2 JOIN first f
        ON t2.val1 = f.val1
  ) a
   GROUP BY val1
)
SELECT * 
  FROM first f JOIN second s
    ON f.val1 = s.val1

Here is SQLFiddle demo

Example for SQLServer2005+

First part of the script combines result of the query into a single variable. Thus we have a names of columns in a PIVOT statement.

   DECLARE @cols varchar(100),
            @dml nvarchar(max)
    SET @cols = N''
    SELECT @cols += ',[val5' + CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS varchar(10)) + '],' 
                  + '[val6' + CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS varchar(10)) + ']'
    FROM (
          SELECT TOP 1 t.someColumn
          FROM dbo.test138 t
          GROUP BY t.someColumn
          ORDER BY COUNT(*) DESC
          ) t2 JOIN dbo.test138 t3 ON t2.someColumn = t3.someColumn

The second part of the instruction dynamically creates SQL, and then use this command.

SET @dml = 
 'SELECT *
  FROM (
        SELECT t1.val1, t1.val2, t1.val3, t1.val4, 
               COALESCE(o2.colName5, o2.colName6) AS colName, 
               COALESCE(o2.val5, o2.val6) AS val
        FROM dbo.test137 t1 CROSS APPLY (
                                         SELECT ''val5'' + CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS varchar(10)), t2.val5, 
                                                ''val6'' + CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS varchar(10)), t2.val6
                                         FROM dbo.test138 t2
                                         WHERE t1.val1 = t2.someColumn                                 
                                         ) o(colName5, val5, colName6, val6)
                            CROSS APPLY (
                                         SELECT o.colName5, NULL, o.val5, NULL
                                         UNION ALL
                                         SELECT NULL, o.colName6, NULL, o.val6
                                         ) o2(colName5, colName6, val5, val6)
        ) x
  PIVOT
 (
  MAX(x.val) FOR colName IN (' + STUFF(@cols, 1, 1, '') + ')
  ) pvt'
--PRINT @dml
EXEC sp_executesql @dml

See demo on SQLFiddle

Try this out if ur return value are only 1 and u just want to use val1 as your second query parameter

DECLARE @val1 NVARCHAR(255)

SELECT val1, val2, val3, val4 from ....

SET @val1 = (Select ordinal_position from information_schema.columns
where Column_Name='@val1' and Table_name = '@yourTableName')

SELECT val5, val6 from anotherTable where someColumn = @val1

Your return result

val1, val2, val3, val4, val51, val61, val52, val62, val53, val63

The return result is based on what u select, in this case, your 2nd query may not work

try to change ur 2nd query to something like below

Select val1,val2,val3, val4, COALESCE(val5,val1), COALESCE(val6,val1)

to put meat on the bones of this you do it like this

Create PROCEDURE GetInfo(
  @Search_For varchar(255)
)
AS
BEGIN
    DECLARE @val1 NVARCHAR(255)
    SET  @val1 = (SELECT MAX(StoredDate) FROM my_archive)
    SELECT line_id, site_code, StoredDate=@val1 FROM line WHERE LineCode=@Search_For 
END

where

 my_archive *contains
+------------------------------+
| StoredDate

line *contains
+------------------------------+
| line_id, site_code, LineCode

gives you

line_id  site_code   StoredDate
1        SF          Jan 18 2018  1:07PM

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM