Where to declare a SET in SQL? - 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.

Related

SQL Select statement - base results upon the value of an alias within statement

I am trying to write a Select statement (comprised of around 20 different joined aliases) that will only return results if the value of one of the aliases created within the same statement equals a certain value.
I'm very green with SQL at this point and therefore don't really know how to phrase this dilemma properly to find the answer elsewhere.
Current code for element being assigned an alias of "cmp_freq":
ISNULL((SELECT GroupValue FROM ClientGroup WHERE ClientKey = c.ClientKey AND GroupCode = 'CMP-FREQ'),'PLEASE UPDATE FIELD') AS cmp_freq
Essentially, I only want results returned for the entire statement where the value of cmp_freq is "30". Is there any way to reference this alias in the where clause of the statement as a whole in order to accomplish this?
There are several ways to accomplish your goal. One way would be to wrap your query in a SELECT and use a WHERE clause, like so:
SELECT i.cmp_freq
FROM (
/* Your existing query */
SELECT
ISNULL((SELECT GroupValue FROM ClientGroup WHERE ClientKey = c.ClientKey AND GroupCode = 'CMP-FREQ'),'PLEASE UPDATE FIELD') AS cmp_freq
FROM MyTable c
) i
WHERE i.cmp_freq = 30
It's difficult to offer other options as there is not enough information in your question.

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 re-use a result set produced by executing a sql query?

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...

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

Insert into using Variables

I have the following SQL query:
Declare #Total_SysDown as int,
#Login_SysDown as int
Set #Total_SysDown = (SELECT SCHED_SYS_DOWN FROM AGT_SC AS S)
Set #Login_SysDown = (SELECT SYS_DOWN FROM AGT_AC AS A)
Insert Into dbo.DATA(DATE,ID,LNAME,FNAME,Total_SysDown,Login_SysDown)
Select C.DATE,C.ID,E.Last_Name,E.First_Name,#Total_SysDown #Login_SysDown
From dbo.AGT as C Inner Join dbo.EMP as E ON C.ID = E.ID
Group by C.ID,C.DATE,E.Last_Name,E.First_Name
This or just the variables with the Select statement gives me an error of Subquery returned than 1 value. From what I understand, this means that I should be inserting one record at a time, but I am unsure how to do this. Is there a while statement I should be putting in, or are my variables actually hindering me in the first place?
At least one of the queries:
(SELECT SCHED_SYS_DOWN FROM AGT_SC AS S)
(SELECT SYS_DOWN FROM AGT_AC AS A)
returns more than 1 row, so you cannot assign it to a scalar variable.
As a temporary solution you can do SELECT TOP 1 to make sure each query returns at most one row.
I don't think the problem is with your INSERT statement at all.
Your problem is in the SET Statements. The SELECT SCHED_SYS_DOWN FROM AGT_SC AS S statement or the other statement is returning more than one value.
When you use SET you are assigning ONE value to the variable. Your SELECT is returning multiple values. Change your query to return only one row.
You're receiving this error because your subqueries return more than one record:
Set #Total_SysDown = (SELECT SCHED_SYS_DOWN FROM AGT_SC AS S)
Set #Login_SysDown = (SELECT SYS_DOWN FROM AGT_AC AS A)
To use variables here, you will need to ensure that only one record is returned from the query, either by using a WHERE clause, TOP 1, or something else. I can't tell for sure by your example, but it sounds like you should be joining those tables to your SELECT query.
SELECT ...
FROM dbo.AGT agt
INNER JOIN AGT_SC sc
ON sc.<joining column> = <joining table>.<joining column>
INNER JOIN AGT_AC ac
ON ac.<joining column> = <joining table>.<joining column>