SQL Column Not Found - sql

I'm trying to build a SQL query to cross checks a couple of columns.
My issue is with the calcontvalue column.
The query works fine until I want to include a Where clause containing it AND calcontvalue = job.contvalue.
SELECT
job.accountno,
job.groupno,
job.contvalue,
job.z1total,
job.z2equip,
job.z3freight,
job.z4pack,
job.z5ancil,
job.z6roy,
job.zrpay,
job.z7paid,
job.z8invtype,
IIF(job.z8invtype <> 0, job.z2equip+job.z5ancil,
IIF(job.z8invtype <> 1, job.z2equip+job.z3freight+job.z4pack+job.z5ancil, 0)) AS calcontvalue,
group.groupno,
group.grouptype,
group.title FROM job
LEFT JOIN group
ON job.groupno = group.groupno
WHERE grouptype = 'J' AND calcontvalue = job.contvalue
The I'm presented with this error:
SQL:Column 'CALCONTVALUE' is not found.
Not sure what to try next.

You cannot use alias in WHERE, use full expression:
SELECT
job.accountno,
job.groupno,
job.contvalue,
job.z1total,
job.z2equip,
job.z3freight,
job.z4pack,
job.z5ancil,
job.z6roy,
job.zrpay,
job.z7paid,
job.z8invtype,
IIF(job.z8invtype <> 0, job.z2equip+job.z5ancil,
IIF(job.z8invtype <> 1, job.z2equip+job.z3freight+job.z4pack+job.z5ancil, 0)) AS calcontvalue,
group.groupno,
group.grouptype,
group.title
FROM job
LEFT JOIN group
ON job.groupno = group.groupno
WHERE grouptype = 'J'
AND IIF(job.z8invtype <> 0, job.z2equip+job.z5ancil,
IIF(job.z8invtype <> 1, job.z2equip+job.z3freight+job.z4pack+job.z5ancil, 0)) = job.contvalue
Also naming table group is bad practise because GROUP is keyword GROUP BY.

Related

USING CASE AS PART OF JOIN ORACLE SQL

I have a query in Oracle SQL Developer to grab data from a raw table (all the data on the raw table are varchars) where I need to "clean" the data when I select it. Have to use a CASE statement to get the store number because sometimes that data isn't in the STORENBR column but can be found in a substring of another column -
SELECT
CASE WHEN m.STORENBR = '0' AND (SUBSTR(m.SENDING_QMGR, 1, 5) = 'PDPOS')
THEN TO_NUMBER((SUBSTR(m.SENDING_QMGR, 8, 4)))
WHEN m.STORENBR = '0' AND (SUBSTR(m.SENDING_QMGR, 1, 8) = 'PROD_POS')
THEN TO_NUMBER((SUBSTR(m.SENDING_QMGR, 9, 4)))
ELSE TO_NUMBER(NVL(m.STORENBR, '0'))
END AS STORENBR,
TO_NUMBER(NVL(m.CONTROLNBR,'0')) AS CONTROLNBR,
TO_NUMBER(NVL(m.LINENBR,'0')) AS LINENBR,
TO_DATE(m.TRANDATE,'YYYY-MM-DD') AS TRANDATE,
TO_NUMBER(NVL(m.NUMMISPRINTED,'0.00'),'99.99') AS NUMMISPRINTED
FROM MISPRINTS_RAW m
WHERE TO_DATE(m.TRANDATE,'YYYY-MM-DD') = '15-MAR-21'
ORDER BY m.STORENBR;
Now I need to also pull an account number from another table (TRANSACTIONS t - not a raw table, so I don't need any CASE or TO_NUMBER to pull data) but I need to join that table on STORENBR, CONTROLNBR, and LINENBR. So how do I use that CASE statement as part of the join to JOIN m.STORENBR on t.STORENBR?
Even if I am not sure about the data structure the following statement should be helpful.
The table with the raw data is "converted" in a subselect, so that a normal join is possible.
SELECT *
FROM (SELECT CASE
WHEN m.storenbr = '0'
AND ( Substr(m.sending_qmgr, 1, 5) = 'PDPOS' ) THEN
To_number(
( Substr(m.sending_qmgr, 8, 4) ))
WHEN m.storenbr = '0'
AND ( Substr(m.sending_qmgr, 1, 8) = 'PROD_POS' ) THEN
To_number(( Substr(m.sending_qmgr, 9, 4) ))
ELSE To_number(Nvl(m.storenbr, '0'))
END AS STORENBR,
To_number(Nvl(m.controlnbr, '0')) AS CONTROLNBR,
To_number(Nvl(m.linenbr, '0')) AS LINENBR,
To_date(m.trandate, 'YYYY-MM-DD') AS TRANDATE,
To_number(Nvl(m.nummisprinted, '0.00'), '99.99') AS NUMMISPRINTED
FROM misprints_raw m) m1,
TRANSACTION t
WHERE t.storenbr = m1.storenbr
AND t.controlnbr = m1.controlnbr
AND t.linenbr = m1.linenbr
AND m1.trandate = DATE '2021-03-15'
ORDER BY m1.storenbr;

Is it possible to replace the following two SQL selects with just one?

Please, observe:
DECLARE #UseFastLane BIT
SELECT TOP 1 #UseFastLane = 1
FROM BackgroundJobService
WHERE IsFastLane = 1;
SELECT TOP 1 bjs.HostName AllocatedAgentHostName,
bjs.ServiceName AllocatedAgentServiceName,
bjs.IsFastLane,
SUM(CASE
WHEN bjw.WorkStatusTypeId IN ( 2, 3, 4, 10 ) THEN 1
ELSE 0
END) AS InProgress
FROM BackgroundJobService bjs
LEFT JOIN BackgroundJobWork bjw
ON bjw.AllocatedAgentHostName = bjs.HostName
AND bjw.AllocatedAgentServiceName = bjs.ServiceName
WHERE bjs.AgentStatusTypeId = 2
AND bjs.IsFastLane = COALESCE(#UseFastLane, 0)
GROUP BY bjs.HostName,
bjs.ServiceName,
bjs.IsFastLane
ORDER BY IsFastLane DESC,
InProgress
I am using two SQL select statements here. Is it possible to use just one top level SQL select statement, nesting another one within?
You can replace the text AND bjs.IsFastLane = COALESCE(#UseFastLane, 0) with this:
AND bjs.IsFastLane = (SELECT Max(IsFastLane)
FROM BackgroundJobService)
which should give you an equivalent query assuming that there are rows in the BackgroundJobService.
If there might be zero rows in BackgroundJobService then you can wrap the select with a COALESCE function to return 0, like this:
COALESCE((SELECT Max(IsFastLane) FROM BackgroundJobService), 0)

Need COUNT from a more complex query

I usually use COUNT within a subquery to grab the desired number, but in this case I need a little help as the query contains too many arguments.
SELECT a.[QueueID]
,a.[CouponID]
,a.[ListingID]
,a.[User_ID]
,b.[CouponID]
,b.[ListingID]
,b.[CouponActive]
,b.[CouponExpire]
,b.[IsDeleted]
,c.[ListingID]
,c.[TypeID]
,c.[LevelID]
,#passedUserID as User_ID
FROM CouponQueue a
JOIN Coupon b
on a.CouponID = b.CouponID
JOIN Listing c
on b.ListingID = c.ListingID
WHERE (a.[User_ID] = #passedUserID)
AND (b.[CouponActive] = 1)
AND (b.[IsDeleted] = 0)
AND (b.[CouponExpire] > DATEADD(dd, -1, GETDATE()) OR b.[CouponExpire] IS NULL)
So lets say this query returns a result of 7 rows. All I need is this number for my VIEW. So I want to limit the ultimate result to a single row so that in the end I get:
[TotalCount] <-- Field name
[7] <-- Result
But not 7 rows of data.. I just need the count from the above query. Still plugging away and trying to learn. I looked at a few other examples but I haven't found one with all the conditions... which is what's messing me up. Please help!
Thank you so much!
Would this work for you?
select count(*) as TotalCOunt from (
SELECT a.[QueueID] /*
,a.[CouponID]
,a.[ListingID]
,a.[User_ID]
,b.[CouponID]
,b.[ListingID]
,b.[CouponActive]
,b.[CouponExpire]
,b.[IsDeleted]
,c.[ListingID]
,c.[TypeID]
,c.[LevelID]
,#passedUserID as User_ID */
FROM CouponQueue a
JOIN Coupon b
on a.CouponID = b.CouponID
JOIN Listing c
on b.ListingID = c.ListingID
WHERE (a.[User_ID] = #passedUserID)
AND (b.[CouponActive] = 1)
AND (b.[IsDeleted] = 0)
AND (b.[CouponExpire] > DATEADD(dd, -1, GETDATE()) OR b.[CouponExpire] IS NULL)
) t
You can remove the columns for the count. They are not actually necessary.
Should be able to just add COUNT(*):
SELECT COUNT(*) as TotalCount
FROM CouponQueue a
JOIN Coupon b
on a.CouponID = b.CouponID
JOIN Listing c
on b.ListingID = c.ListingID
WHERE (a.[User_ID] = #passedUserID)
AND (b.[CouponActive] = 1)
AND (b.[IsDeleted] = 0)
AND (b.[CouponExpire] > DATEADD(dd, -1, GETDATE()) OR b.[CouponExpire] IS NULL)
Good luck.
You can put the below sample on your SQL Developer to run for the count:
SELECT count(*) as totalCount (*-open a parentheses - your original query -close the parentheses*)

SQL Query takes to long to return data

Looking for a better way to write this query and my SQL skills aren't great, basic really so looking for any pointers to make this better. This is only the first two columns and the full report will have a further 10.
I'm taking a specific set of repair types and doing analysis on them with counts and calculations. The 1st is jobs brought forward to the current financial year and the second is total amount of jobs currently received.
SELECT
"Type",
(
SELECT
NVL (COUNT(jjo.jjobno), 0)
FROM
jjobh jjo
WHERE
jjo.jclcode = 'L'
AND jjo.jstatus <> '6'
AND jjo.year_rec <> (
SELECT
sub_code
FROM
code_table
WHERE
main_code = 'YEAR'
)
AND (
week_comp IS NULL
OR year_comp = (
SELECT
sub_code
FROM
code_table
WHERE
main_code = 'YEAR'
)
)
AND jjo.jrepair_type = "Type"
) AS "B/F",
(
SELECT
NVL (COUNT(jjo.jjobno), 0)
FROM
jjobh jjo
WHERE
jjo.jclcode = 'L'
AND jjo.jstatus <> '6'
AND jjo.year_rec = (
SELECT
sub_code
FROM
code_table
WHERE
main_code = 'YEAR'
)
AND jjo.jrepair_type = "Type"
) AS "Recvd"
FROM
(
SELECT
rep.repair_type_code AS "Type"
FROM
repair_type rep
WHERE
rep.client = 'L'
AND rep.work_centre = '004682'
ORDER BY
rep.repair_type_code
)
ORDER BY
"Type";
Your code is a mess. I suspect you want something like:
SELECT jjo.jrepair_type, count(*) as valbf
FROM (SELECT coalesce(COUNT(jjo.jjobno), 0)
FROM jjobh jjo cross join
(SELECT sub_code
FROM code_table
WHERE main_code = 'YEAR'
) sc
WHERE jjo.jclcode = 'L' AND
jjo.jstatus <> '6' AND
jjo.year_rec <> sc.sub_code AND
(week_comp IS NULL OR
year_comp = sc.sub_code
)
) jjo join
(SELECT rep.repair_type_code AS "Type"
FROM repair_type rep
WHERE rep.client = 'L' AND
rep.work_centre = '004682'
) rtc
on jjo.jrepair_type = rtc.repair_type_code
group by jjo.jrepair_type;
It looks like you want to join the "jjo" table to the "repair type code" table, producing information about each repair type. The order by in the subquery is useless.
My suggestion is to move the "jjo" table to the outer "from". You should also move the WHERE clauses to the outermost WHERE clause (which I didn't do). I haven't quite figured out the date logic, but this might get you on the right track.

sql server query how to have multiple column comparision with subquery

How can I make the update query to work based on the sub query?
How can I compare all these columns in the sub query to the columns in the update statement?
Is there some neat and clean way to do it?
The query I am trying with it is shown below:
UPDATE Temp_CropData
SET RecordStatus = 0,
Remarks = ISNULL(Remarks, '') +' Duplicate Records'
WHERE
(SELECT Commodity ,City,Period,CropCondition
FROM [Temp_CropData]
GROUP BY DDate,Commodity,City,Period,CropCondition
HAVING count(*) >1)
Try using MERGE:
MERGE INTO Temp_CropData
USING (
SELECT Commodity, City, Period, CropCondition
FROM Temp_CropData
GROUP
BY DDate, Commodity, City, Period, CropCondition
HAVING COUNT(*) > 1
) AS source
ON Temp_CropData.Commodity = source.Commodity
AND Temp_CropData.City = source.City
AND Temp_CropData.Period = source.Period
AND Temp_CropData.CropCondition = source.CropCondition
WHEN MATCHED THEN
UPDATE
SET RecordStatus = 0,
Remarks = ISNULL(Remarks, '') + ' Duplicate Records';
I'm slightly suspicious of the fact that your subquery's SELECT and GROUP BY clauses do not match, though (i.e. DDate is in the GROUP BY but not the SELECT).
Try this:
UPDATE cd
SET RecordStatus = 0,
Remarks = ISNULL(Remarks, '') +' Duplicate Records'
FROM Temp_CropData cd
JOIN (SELECT Commodity ,City,Period,CropCondition
FROM [Temp_CropData]
GROUP BY DDate,Commodity,City,Period,CropCondition
HAVING count(*) >1) dup
ON cd.DDate = dup.DDate AND cd.Commodity=dup.Commodity AND cd.City = dup.City
AND cd.Period = dup.Period AND cd.CropCondition = dup.CropCondition