Conflict in Case Condition in Sql Server query - sql

select CASE when (select distinct BR.BorrowerID from tblBorrow BR
inner join tblWorker W on W.ContractorID=BR.BorrowerID
inner join tblBorrowWorker TWB on TWB.WorkerID=W.WorkerID
inner join tblBorrowWorkerAssign TBWA on TWB.BorrowWorkerAssignmentID=TBWA.BorrowWorkerAssignmentID where TWB.WorkerID=11276) then 'BR.BorrowerID' else 'NotBorrowed' end as BorrowedStatus
Here actually in 'Then' Condition i want to display the BorrowerID,here the subquery part is working well and returning ID ,but when i add with CASE statment its giving an Error
"An expression of non-boolean type specified in a context where a condition is expected, near 'then'."This query is a part of my stored Procedure.What will be the solution

CASE clause expects a boolean condition. Can you use Exists() to check for true condition? Try using exists() for inner select statement (starting with select distinct BR.BorrowerID from tblBorrow BR...)

If you mean to show the value of BR.BorrowerID from the subquery instead of the 'BR.BorrowerID' string constant, you could try the following (assuming you've ensured that the subquery returns no more than one row):
SELECT
ISNULL(
(
SELECT DISTINCT CAST(BR.BorrowerID AS varchar(15))
FROM tblBorrow BR
INNER JOIN tblWorker W ON W.ContractorID = BR.BorrowerID
INNER JOIN tblBorrowWorker TWB ON TWB.WorkerID = W.WorkerID
INNER JOIN tblBorrowWorkerAssign TBWA ON TWB.BorrowWorkerAssignmentID = TBWA.BorrowWorkerAssignmentID
WHERE TWB.WorkerID=11276
),
'NotBorrowed'
)
On the other hand, if that was a full query (not a part of a bigger one) in your post, the following might also be an option:
SELECT DISTINCT ISNULL(CAST(BR.BorrowerID AS varchar(15)), 'NotBorrowed')
FROM
(SELECT 1) x (x)
LEFT JOIN
tblBorrow BR
INNER JOIN tblWorker W ON W.ContractorID = BR.BorrowerID
INNER JOIN tblBorrowWorker TWB ON TWB.WorkerID = W.WorkerID
INNER JOIN tblBorrowWorkerAssign TBWA ON TWB.BorrowWorkerAssignmentID = TBWA.BorrowWorkerAssignmentID
ON TWB.WorkerID = 11276
The (SELECT 1) x (x) "table" is only there to ensure the resulting set is not empty in case the right side of the left join returns no rows.

Related

How to fix SQL query to Left Join a subquery with Where clause?

I'm new to SQL and I'm not certain why I am getting this error. I am trying to left join a sub-query to another query in sql developer.
This is the first query,
SELECT DISTINCT
tl.species,
ag.age
FROM
age_list ag,
tree_list tl
WHERE
ag.tree_id = tl.tree_id
And then the sub-query I would like to left join where the tree_id = tree_number is,
SELECT DISTINCT
sl.tree_spon,
sl.tree_number
FROM spon_list sl
WHERE
sl.tree_spon < 10
When trying to do this I've tried to use,
SELECT DISTINCT
tl.species,
ag.age,
q1.tree_spon
FROM
age_list ag,
tree_list tl
LEFT OUTER JOIN (SELECT DISTINCT
sl.tree_spon,
sl.tree_number
FROM spon_list sl
WHERE sl.tree_spon < 10) q1 on q1.tree_number = tree_list.tree_id
WHERE
ag.tree_id = tl.tree_id
Whatever I change in terms of the alias' for the columns and tables I always get the error, "ORA-00904: invalid identifier error", and that "tree_list.tree_id is invalid identifier", though separately the queries run fine.
Can anyone help, is it an issue with both queries joining on the tl.tree_id?
You can use the ANSI join syntax throughout (rather than mixing in legacy comma joins), joining on ag.tree_id = sl.tree_number (or tl.tree_id = sl.tree_number but they're both equal given the previous join) and putting the filter on sl.tree_spon < 10 into the ON clause as well:
SELECT DISTINCT
tl.species,
ag.age,
sl.tree_spon,
sl.tree_number
FROM age_list ag
INNER JOIN tree_list tl
ON (ag.tree_id = tl.tree_id)
LEFT OUTER JOIN spon_list sl
ON (ag.tree_id = sl.tree_number AND sl.tree_spon < 10)
Change tree_list.tree_id to tl.tree_id

Subquery returned more than 1 value - Error Message

I'm getting the error message:
Subquery returned more than 1 value. This is not permitted when the subquery follows =,!=,<,<=,>,=> or when the subquery is used as an expression.
Below is a small subset of a larger query, but the part of the query to determine the Test_Col value is essentially where I'm running into this issue. The query by itself works, but when I use it as a subquery within the larger query, I get this error message in SQL Server. Any ideas on where I'm going wrong?
select
distinct(nml.scode) Loan_Num,
(select isnull(sum(isnull(t.smtd, 0) + isnull(t.sbeginbudget, 0)), 0)
from nmloan nml
left join property p on nml.hprop = p.hmy
left join total t on p.hmy = t.hppty
where nml.hprop in (2380, 3348)
and t.umonth between '1/1/1900' and '9/30/2021'
and t.ibook = 1 and t.hacct in (1349, 1348, 1347, 1345, 1343, 1342, 1341, 1339, 1338, 1337, 1336, 1334, 1332, 1690, 1682, 1331)
group by nml.hprop) Test_Col
from
nmloan nml
left join
property p on nml.hprop = p.hmy
left join
total t on p.hmy = t.hppty
left join
acct ac on ac.hmy = t.hacct
left join
nmborrower nmb on nml.hmy = nmb.hnmloan
left join
person ps on nmb.hmyperson = ps.hmy
left join
nmloanterms nmt on nml.hmy = nmt.hloan
left join
nmcollateralxref nmx on nml.hmy = nmx.hnmloan
left join
nmcollateral nmc on nmx.hnmcollateral = nmc.hmy
left join
loanbut1 lb1 on nml.hmy = lb1.hcode
left join
NMLedger l ON nml.hmy = l.hNMLoan
left join
nmLedgerDetail d on l.hmy = d.hNMLedger
left join
loanbut7 lb on nml.hmy = lb.hcode
left join
loanbut8 lb8 on nml.hmy = lb8.hcode
left join
loanbut9 lb9 on nml.hmy = lb9.hcode
where
nml.hprop in (2380, 3348)
and lb.lrPeriod in ('9/30/2021')
and lb9.lrnDate in ('9/30/2021')
group by
nml.hprop, nml.scode
In SQL Server DB if your subquery is written after the select command where we wrote field name list, then your subquery must be return only one record and only one field, else you will get an error. In your script, you wrote subquery before the from command, after this Loan_Num,. I did a little research on your subquery. Your subquery will return more than 1 record in most cases. The reason is that you wrote group by nml.hprop and after the where command you wrote this condition nml.hprop in (2380, 3348). I would have written this query for you myself, but I don't know your business logic and what need you. If your subquery must return more than 1 record, so you must join this subquery to the main query, using inner join or left join, you can not write this subquery on the field list.
Turns out that since my subquery's alias, nml, has the same alias as the parent query, nml (for the nmLoan table), it was did not work.
Upon changing my subquery's alias to nl and leaving the parent query's alias to nml, that actually worked and I was able to generate multiple results.

How to do operations between a column and a subquery

I would like to know how I can do operations between a column and a subquery, what I want to do is add to the field Subtotal what was obtained in the subquery Impuestos, the following is the query that I am using for this case.
Select
RC.PURCHID;
LRC.VALUEMST as 'Subtotal',
isnull((
select sum((CONVERT(float, TD1.taxvalue)/100)*LRC1.VALUEMST ) as a
FROM TAXONITEM TOI1
inner join TAXDATA TD1 ON (TD1.TAXCODE = TOI1.TAXCODE and RC.DATAAREAID = TD1.DATAAREAID)
inner join TRANS LRC1 on (LRC1.VEND = RC.RECID)
WHERE TOI1.TAXITEMGROUP = PL.TAXITEMGROUP and RC.DATAAREAID = TOI1.DATAAREAID
), 0) Impuestos
from VEND RC
inner join VENDTABLE VTB on VTB.ACCOUNTNUM = RC.INVOICEACCOUNT
inner join TRANS LRC on (LRC.VEND = RC.RECID)
inner join PURCHLINE PL on (PL.LINENUMBER =LRC.LINENUM and PL.PURCHID =RC.PURCHID)
where year (RC.DELIVERYDATE) =2021 and RC.PURCHASETYPE =3 order by RC.PURCHID;
Hope someone can give me some guidance when doing operations with subqueries.
A few disjointed facts that may help:
When a SELECT statement returns only one row with one column, you can enclose that statement in parenthesis and use it as a plain value. In your case, let's say that select sum(......= TOI1.DATAAREAID returns 500. Then, your outer select's second column is equivalent to isnull(500,0)
You mention in your question "subquery Impuestos". Keep in mind that, although you indeed used a subquery as we mentioned earlier, by the time it was enclosed in parentheses it is not treated as a subquery (more accurately: derived table), but as a value. Thus, the "Impuestos" is only a column alias at this point
I dislike and avoid subqueries before the from, makes things much harder to read. Here is a solution with apply which will keep your code mostly intact:
Select
RC.PURCHID,
LRC.VALUEMST as 'Subtotal',
isnull(subquery1.a, 0) as Impuestos
from VEND RC
inner join VENDTABLE VTB on VTB.ACCOUNTNUM = RC.INVOICEACCOUNT
inner join TRANS LRC on (LRC.VEND = RC.RECID)
inner join PURCHLINE PL on (PL.LINENUMBER =LRC.LINENUM and PL.PURCHID =RC.PURCHID)
outer apply
(
select sum((CONVERT(float, TD1.taxvalue)/100)*LRC1.VALUEMST ) as a
FROM TAXONITEM TOI1
inner join TAXDATA TD1 ON (TD1.TAXCODE = TOI1.TAXCODE and RC.DATAAREAID = TD1.DATAAREAID)
inner join TRANS LRC1 on (LRC1.VEND = RC.RECID)
WHERE TOI1.TAXITEMGROUP = PL.TAXITEMGROUP and RC.DATAAREAID = TOI1.DATAAREAID
) as subquery1
where year (RC.DELIVERYDATE) =2021 and RC.PURCHASETYPE =3 order by RC.PURCHID;

Need to understand multiple joins correctly

I was trying to join 3 tables - CurrentProducts, SalesInvoice and SalesInvoiceDetail. SalesInvoiceDetail contains FK/foreign key to the other two tables and some other columns. The first query is ok but the second is not. My question comes at the end of the code.
Right
select *
from CurrentProducts inner join
(dbo.SalesInvoiceDetail inner join dbo.SalesInvoice
on dbo.SalesInvoiceDetail.InvoiceID = dbo.SalesInvoice.InvoiceID
)
on dbo.SalesInvoiceDetail.ProductID = dbo.CurrentProducts.ProductID
Wrong
select *
from CurrentProducts inner join
(select * from
dbo.SalesInvoiceDetail inner join dbo.SalesInvoice
on dbo.SalesInvoiceDetail.InvoiceID = dbo.SalesInvoice.InvoiceID
)
on dbo.SalesInvoiceDetail.ProductID = dbo.CurrentProducts.ProductID
error - Incorrect syntax near the keyword 'on'.
Why is the second query wrong ? Isn't it conceptually the same as the first one ? That is inside join makes a result set. We select * the result set and then join this result set to CurrentProducts ?
The first query is a "plain" join expressed with an older syntax. It can be rewritten as:
select
*
from
CurrentProducts
inner join dbo.SalesInvoiceDetail
on dbo.SalesInvoiceDetail.ProductID = dbo.CurrentProducts.ProductID
inner join dbo.SalesInvoice
on dbo.SalesInvoiceDetail.InvoiceID = dbo.SalesInvoice.InvoiceID
The second query is a join where the second table is a subquery. When you join on a subquery, you must assign an alias to it and use that alias to refer to the columns returned by the subquery:
select
*
from
CurrentProducts
inner join (select *
from dbo.SalesInvoiceDetail
inner join dbo.SalesInvoice
on SalesInvoiceDetail.InvoiceID = SalesInvoice.InvoiceID
) as foo on foo.ProductID = dbo.CurrentProducts.ProductID
You need to alias the inner query. Also, in the first one the parentheses are not needed.
select *
from CurrentProducts inner join
(select * from
dbo.SalesInvoiceDetail inner join dbo.SalesInvoice
on dbo.SalesInvoiceDetail.InvoiceID = dbo.SalesInvoice.InvoiceID
) A
on A.ProductID = dbo.CurrentProducts.ProductID

Subquery with multiple joins involved

Still trying to get used to writing queries and I've ran into a problem.
Select count(region)
where (regionTable.A=1) in
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
)
The inner query gives an ID number in one column, the amount of times they appear in the table, and then a bit attribute if they are in region A. The outer query works but the error I get is incorrect syntax near the keyword IN. Of the inner query, I would like a number of how many of them are in region A
You must specify table name in query before where
Select count(region)
from table
where (regionTable.A=1) in
And you must choose one of them.
where regionTable.A = 1
or
where regionTable.A in (..)
Your query has several syntax errors. Based on your comments, I think there is no need for a subquery and you want this:
select jxn.id, count(jxn.id) as counts, regionTable.A
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id, regionTable.A
which can be further simplified to:
select jxn.id, count(jxn.id) as counts
, 1 as A --- you can even omit this line
from jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
where regionTable.A = 1
group by jxn.id
You are getting the error because of this line:
where (regionTable.A=1)
You cannot specify a condition in a where in clause, it should only be column name
Something like this may be what you want:
SELECT COUNT(*)
FROM
(
select jxn.id, count(jxn.id) as counts, regionTable.A
from
jxn inner join
V on jxn.id = V.id inner join
regionTable on v.regionID = regionTable.regionID
group by jxn.id, regionTable.A
) sq
WHERE sq.a = 1