How to re-use a result set produced by executing a sql query? - sql

I'm using PostgreSQL 8.4. I need to assign the result set produced by the query to a variable that I can use in another query. For instance, I have the following query:
SELECT *
FROM
-- some_table_expression
I need to use the result of that query in another query like the following:
FOR i IN 1 .. array_upper(players, 1)
LOOP
UPDATE partner.daily_profit
SET banner_id = (SELECT banner_id FROM _RESULT_OF_THE_QUERY_ WHERE id = players[i]),
WHERE partner.daily_profit.player_id = players[i]
END LOOP
Is there a way to do this in PostgreSQL 8.4? I would prefer to not insert the query string as subquery...

Related

Where to declare a SET in SQL?

I have been attempting to figure out where I can SET a variable in an SQLQuery. I have 2 different select statements that will have a different WHERE clause depending on the answer to an IF statement, but I would like to only have to run the query to make SET this variable once, and since I am already running the code to find this particular table, I'd like to do it in the first SELECT statement.
The variable I am trying to SET is called regType
SELECT S.subID, C.cKey
FROM Comp AS C
JOIN JData AS J ON J.pKey = C.primary
JOIN Sub AS S ON J.fKey = S.pKey
WHERE ( //This is where I need the variable// )
I want to create a variable because I have a second SELECT that uses the same WHERE clause with the same conditions on it.
Where in this can I SET a variable within the SELECT statement so that I can use it in my WHERE?
It makes no sense to "set" a variable in a where clause - maybe you mean in the SELECT?
SELECT
S.subID,
C.cKey,
#regType = ???
FROM Comp AS C
JOIN JData AS J ON J.pKey = C.primary
JOIN Sub AS S ON J.fKey = S.pKey
WHERE ( ... )
Note that the variable will not be accessible in your WHERE clause of that query since the WHERE clause is evaluated before the SELECT. You can either repeat the expression that you're using in the SET or set the variable before you execute the query.

How to run a query several times?

I have a simple query that I want to run an unknown number of times (depending on given value from the table)
select *
from lotTable
where lot = '1111'
I want to run that query X time depending on the cell called 'code' in the same lot line.
I try to use unsuccessfully for loops in PL/SQL.
This is the code I tried to run:
DECLARE Counter INT
DECLARE MaxC INT
SET Counter = 0
SET MaxC = (select code from lotTable where lot='1111')
while MaxC => Counter
BEGIN
SET Counter += 1
select *
from lotTable
where lot = '1111'
END
and this is the error
If you just want the specific row from the table repeated code times, you coudl use a hierarchical query:
select *
from (
select *
from lotTable
where lot = 1111
)
connect by level <= code;
The inner query identifies the single row you're interested in, and the outer query uses the connect by level construct to repeat the row.
SQL Fiddle demo.
Without the inner query connect by gets a bit confused (see this example with incorrect results); there are workarounds and you could also use recursive subquery factoring to avoid that, but this is simpler.

performing an update query with a select subquery returning either the same value for ALL of the records or ora-01427 error

I need to update a column in one table with the results from a select sub-query (and they should ultimately be different). But When I do this, I either get the exact same number for the hundreds of records, or I get the ORA-01427: single row sub-query returns more than one row query. error.
Can you please take a look and see what it is that I am overlooking? (I could just be overlooking something simple for all I know)
UPDATE WD_PRODUCT_CLASS
SET CURRENT_CASES = ( WITH STUFF_COUNT AS
(
SELECT sum(CURRENT_DETAIL.COMBINED_QTY) AS TOTAL_CASES
FROM CURRENT_DETAIL, SKU_MAJORS, WD_PRODUCT_CLASS
WHERE CURRENT_DETAIL.LOC_ID =
&PARM_LOC_ID
AND CURRENT_DETAIL.INVEN_ID = SKU_MAJORS.INVEN_ID
AND WD_PRODUCT_CLASS.CATEGORY = SKU_MAJORS.CONT_DESC
GROUP BY WD_PRODUCT_CLASS.CATEGORY
)
(
SELECT SUM(Z.TOTAL_CASES) FROM STUFF_COUNT Z
)
);
Maybe you need someting like this:
UPDATE WD_PRODUCT_CLASS wpc
SET wpc.CURRENT_CASES = (
SELECT sum(cd.COMBINED_QTY)
FROM CURRENT_DETAIL cd join SKU_MAJORS sm ON cd.INVEN_ID = sm.INVEN_ID
WHERE cd.LOC_ID = &PARM_LOC_ID
AND sm.CONT_DESC = wpc.CATEGORY
)
WHERE 1=1; -- if you don't set a condition all the rows will be updated
Your query updates the table with the same values because you're using a not correlated subquery in the SET clause. This subquery don't depends on the parent query, so it's calculated only once.
I suppose you need a correlated subquery so I changed your update + removed some extra parts.

How to save data in SQL that use Data-Retrieval Functions?

I am retreiving values from a Table which in turn i am comparing with values from another table using the SQL keywords 'EXCEPT'
My query looks something like follows
SELECT DISTINCT TDC_TREE_FAMILY_CLASSIFICATION AS DPC_Level1,
TDC_TREE_CLASSIFICATION AS DPC_Level2,
TDC_TREE_SUB_CLASSIFICATION AS DPC_Level3
FROM TD_DATA_PACK_CONTENTS
EXCEPT
SELECT DPC_Level1,DPC_Level2,DPC_Level3 FROM DATA_PACK_CATEGORIES
ORDER BY DPC_Level1
Now this query works fine . What i want to do is save the results in a single string variable.
So I declare 3 temps variables to save the values of DPC_Level1,Lvl2,Lvl3 and then i can join them into a single string variable.
So i modify my Query like this.
SELECT DISTINCT #m_DPC_Level11=TDC_TREE_FAMILY_CLASSIFICATION AS DPC_Level1
,#m_DPC_Level2=TDC_TREE_CLASSIFICATION AS DPC_Level2,
,#m_DPC_Level13=TDC_TREE_SUB_CLASSIFICATION AS DPC_Level3
FROM TD_DATA_PACK_CONTENTS
EXCEPT
SELECT DPC_Level1,DPC_Level2,DPC_Level3 FROM DATA_PACK_CATEGORIES
ORDER BY DPC_Level1
But this throws the error
'A SELECT statement that assigns a value to a variable must not be
combined with data-retrieval operations'
. How i resolve this issue. I am using SQL Server 2008
I would go for a subquery
select #m_DPC_LEvel11 = DPC_Level1,
#m_DPC_Level2 = DPC_Level2,
#m_DPC_Level13 = DPC_Level3,
FROM
(SELECT DISTINCT TDC_TREE_FAMILY_CLASSIFICATION AS DPC_Level1,
TDC_TREE_CLASSIFICATION AS DPC_Level2,
TDC_TREE_SUB_CLASSIFICATION AS DPC_Level3
FROM TD_DATA_PACK_CONTENTS
EXCEPT
SELECT DPC_Level1,DPC_Level2,DPC_Level3 FROM DATA_PACK_CATEGORIES
ORDER BY DPC_Level1) s

Regarding joins and subquery

I have below query that I am using ..
select * from app_subsys_param where assp_name like '%param_name%'
where param_name is the name of the parameter. From this query we will get the assp_id corresponding to the parameter. With this id we look up into app_subsys_parmval table to get the value of the parameter.
update app_subsys_parmval set aspv_value = 'true' where assp_id = id_val
Now instead of separately launching the two sql statements , I want to combime both of them as one is there any sub query or join mechanism that can combine both of them in one statement , please advise
You need to use UPDATE .. FROM syntax:
UPDATE app_subsys_paramval
SET aspv_value = 'true'
FROM app_subsys_param
WHERE app_subsys_param.id = app_subsys_paramval.id
AND app_subsys_param.value LIKE '%param_name%';
Use a subselect in your update statement:
UPDATE app_subsys_parmval
SET aspv_value = 'true'
WHERE id_val = (SELECT assp_id
FROM app_subsys_param
WHERE assp_name LIKE '%param_name%')
Note, I am assuming a bit about what's in the * of your select *.
Look at the MERGE statement. This is the ANSI SQL:2003 standard for UPDATE … FROM.
Documentation:
MERGE for DB2 for Linux/UNIX/Windows
MERGE for DB2 z/OS 9.1