Join On conditional column SQL - sql

I'm trying to do a LEFT join on a created column(y_prcs_new) in SQL but I get the next error:
"Column 'y_prcs_new' cannot be resolved"
This is the query:
SELECT
sh.i_rqst,
sh.y_rqst,
sh.c_close_reason,
CASE WHEN sh.y_prcs IS NULL THEN 3
WHEN sh.y_prcs = 1 AND sh.c_close_reason = 5 THEN 3
WHEN (sh.y_prcs IS NOT NULL OR sh.y_prcs != 1) AND sh.c_close_reason != 5 THEN sh.y_prcs
END AS y_prcs_new,
fr.t_close_reason
FROM st_hist sh
LEFT JOIN
(SELECT DISTINCT fr.c_close_reason, fr.t_close_reason, fr.y_prcs
FROM sRsn fr) AS fr
ON sh.c_close_reason = fr.c_close_reason
AND y_prcs_new = fr.y_prcs
Do you know how can fix it?

You query is incorrect as join statement executes first and then select statement in the end of the query, so on join query could not find y_prcs_new.
select
i_rqst,
y_rqst,
c_close_reason,
y_prcs_new,
t_close_reason
from
(
SELECT
i_rqst,
y_rqst,
c_close_reason,
CASE WHEN y_prcs IS NULL THEN 3
WHEN y_prcs = 1 AND c_close_reason = 5 THEN 3
WHEN (y_prcs IS NOT NULL OR y_prcs != 1) AND c_close_reason != 5 THEN y_prcs
END AS y_prcs_new
FROM st_hist
) sh
LEFT JOIN
( SELECT
DISTINCT c_close_reason,
t_close_reason,
y_prcs
FROM sRsn
) fr
ON sh.c_close_reason = fr.c_close_reason
AND sh.y_prcs_new = fr.y_prcs

Related

Conditionally adding a column in a SQL query

I'm trying to add a conditional SELECT column in a query and I'm having trouble writing it out:
SELECT v.GLTypeID,
v.something,
v.somethignElse,
CASE WHEN (SELECT TOP 1 Value FROM InterfaceParam WHERE InterfaceId = 0 AND Descr = 'gf') = 1 THEN a.CreditID ELSE NULL END AS CreditMemoID
FROM vGLDetails2 v
....
LEFT OUTER JOIN AssociationFund f
ON v.FundID = f.FundID
LEFT JOIN dbo.APLedger a ON v.RelID = a.APLedgerID AND v.RelTypeID IN (39, 40)
....
ORDER BY v.Code;
The query above works, however if the CASE statement is still returning an additional column regardless of the result of the subquery. How can I remove it if the subquery doesn't return a row?
How can I do this?
Change the location of AS. For example:
SELECT v.GLTypeID,
v.something,
v.somethignElse,
CASE WHEN (
SELECT TOP 1 Value
FROM InterfaceParam
WHERE InterfaceId = 0 AND Descr = 'creditMemo') = 1
THEN a.CreditID -- AS is not valid here
END AS CreditMemoID -- AS is valid here
FROM vGLDetails2 v
....
LEFT OUTER JOIN AssociationFund f
ON v.FundID = f.FundID
LEFT JOIN dbo.APLedger a ON v.RelID = a.APLedgerID AND v.RelTypeID IN (39, 40)
....
ORDER BY v.Code;
Note: I removed ELSE NULL since this is the default behavior of CASE.

SQL query case when then in where clause

I read a lot of similar questions but didn't find a solution for me. Basically I would like to have a where clause (AND PEKP.VORGANGS_ART = 'BE') only if a special condition (PFSP.EINKAUFS_KZ = 2) is true.
I tried in many ways like that:
SELECT *
FROM PFSP
LEFT OUTER JOIN PFAK on PFSP.RUECKMELDE_NR = PFAK.RUECKMELDE_NR
LEFT OUTER JOIN PEKP ON (PFSP.BESTELL_NR=PEKP.VORGANGS_NR)
AND (PFSP.BESTELL_POS_NR=PEKP.VORGANGS_POS_NR)
LEFT OUTER JOIN PMLB ON PFSP.KOMPONENTEN_ARTIKEL_NR=PMLB.ARTIKEL_NR
WHERE PFAK.KD_VORGANGS_NR = '910-001213'
AND PFSP.RUECKMELDE_STATUS = '3'
AND PFSP.BESCHAFFUNGSKENNER = 'F'
AND CASE PFSP.EINKAUFS_KZ
WHEN 2 THEN PEKP.VORGANGS_ART = 'BE'
END
but I keep getting errors:
wrong syntax near '='"
Skip the CASE, use AND/OR instead:
AND (PFSP.EINKAUFS_KZ <> 2 OR PEKP.VORGANGS_ART = 'BE')
If PFSP.EINKAUFS_KZ = 2, then PEKP.VORGANGS_ART must be equal to 'BE'.
If PFSP.EINKAUFS_KZ <> 2, it doesn't matter what PEKP.VORGANGS_ART is.
With this CASE expression:
AND 1 = CASE
WHEN PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART = 'BE' THEN 1
WHEN PFSP.EINKAUFS_KZ = 2 THEN 0
ELSE 1
END
The order of the conditions is important.
You probably want something like:
AND (
(PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART='BE')
OR PFSP.EINKAUFS_KZ <> 2 --You may need to catch NULL as well
)
SELECT *
FROM PFSP
LEFT OUTER JOIN PFAK on PFSP.RUECKMELDE_NR = PFAK.RUECKMELDE_NR
LEFT OUTER JOIN PEKP ON (PFSP.BESTELL_NR=PEKP.VORGANGS_NR)
AND (PFSP.BESTELL_POS_NR=PEKP.VORGANGS_POS_NR)
LEFT OUTER JOIN PMLB ON PFSP.KOMPONENTEN_ARTIKEL_NR=PMLB.ARTIKEL_NR
WHERE PFAK.KD_VORGANGS_NR = '910-001213'
AND PFSP.RUECKMELDE_STATUS = '3'
AND PFSP.BESCHAFFUNGSKENNER = 'F'
AND ((PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART = 'BE') OR (PFSP.EINKAUFS_KZ <> 2) )

Use if in where statement

I have 4 table:
Table_op_type
Table_maintenancetype
Table_repair_time
Table_repair_type
Each table has one column that can true or false and I have one Table_maintenancereport that has many columns and 4 columns in Table_maintenancereport foreign key given from 4 up table when I select Table_maintenancereport and one row in each table is true code working fine but when more than one row returned from table give this error.
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
How can I fix it?
My code is:
SELECT *
FROM Table_maintenancereport
WHERE mtypeid IN (IIF(#smtype = 1, (SELECT Table_maintenancetype.id FROM Table_maintenancetype WHERE enable_search = 1), mtypeid))
AND op_typeid IN (IIF(#sop IN (1), (SELECT Table_op_type.id FROM Table_op_type WHERE enable_search = 1), op_typeid))
AND repaire_timeid IN (IIF(#stime IN (1), (SELECT Table_repair_time.id FROM Table_repair_time WHERE enable_search = 1), repaire_timeid))
AND repaire_typeid IN (IIF(#stype = 1, (SELECT Table_repair_type.id FROM Table_repair_type WHERE enable_search = 1), repaire_typeid));
You need to fix the where conditions. You can do this with basic logic operators. Sets cannot be returned by iif() or by case() expressions.
So:
WHERE (#smtype <> 1 OR
mtypeid IN (SELECT Table_maintenancetype.id FROM Table_maintenancetype WHERE enable_search = 1)
) AND
(#sop <> 1 OR
op_typeid IN (SELECT Table_op_type.id FROM Table_op_type WHERE enable_search = 1)
) AND
(#stime <> 1 OR
repaire_timeid IN (SELECT Table_repair_time.id FROM Table_repair_time WHERE enable_search = 1)
) AND
(#stype <> 1 OR
repaire_typeid IN (SELECT Table_repair_type.id FROM Table_repair_type WHERE enable_search = 1)
);
If I am interpreting what you are trying to do correctly:
SELECT *
FROM Table_maintenancereport mr
LEFT OUTER JOIN Table_maintenancetype mt ON mr.mtypeid = mt.id AND enable_search = 1
LEFT OUTER JOIN Table_op_type ot ON mr.op_typeid = ot.id AND enable_search = 1
LEFT OUTER JOIN Table_repair_time rt ON mr.repaire_timeid = rt.id AND enable_search = 1
LEFT OUTER JOIN Table_repair_type rty ON mr.repaire_typeid = rty.id AND enable_search = 1
WHERE (ISNULL(#smtype,-1) != 1 OR mt.id IS NOT NULL)
AND (ISNULL(#sop,-1) != 1 OR ot.id IS NOT NULL)
AND (ISNULL(#stime,-1) != 1 OR rt.id IS NOT NULL)
AND (ISNULL(#stype,-1) != 1 OR rty.id IS NOT NULL)
so for each #variable, if it is set to 1, the corresponding field has to be one of the search enabled ids to appear in the output. If a variable is not set to 1, then it will not filter the corresponding field.
Maybe you can use CASE WHEN statement in where clause like:
select
*
from
Table_maintenancereport
where
case
when #smtype = 1 then mtypeid in (
select Table_maintenancetype.id
from
Table_maintenancetype
where
enable_search = 1)
else mtypeid = mtypeid end
....

Get the sum of a count column in SQL

I have the following query
SELECT
dtc.coupon_type_company_name,
COUNT(*) * dtc.coupon_type_company_coupon_amount AS 'Total_Coupon_To_Be_Used',
dtc.coupon_type_company_coupon_months_combinable
FROM
[dbo].[coupon_type_Company_User] dtcu
JOIN
coupon_type_Company dtc ON dtcu.coupon_type_Company_ID = dtc.id
JOIN
person p ON dtcu.userID = p.userID
WHERE
coupon_type_company_coupon_is_combinable = 1
OR coupon_type_company_has_coupon = 1
AND dtc.companyID = 1081
AND p.is_active = 1
GROUP BY
dtc.coupon_type_company_name,dtc.coupon_type_company_coupon_amount,
dtc.coupon_type_company_coupon_months_combinable
This returns the following:
What I want to have however is just one column and one row that should take the SUM of my middle column (count(*)*dtc.coupon_type_company_coupon_amount).
How could I achieve this and prevent doing this in my code backend (C#)
You can wrap your query like this:
SELECT SUM(Total_Coupon_To_Be_Used) AS the_sum
FROM (
your query
) s
Use a "Table Expression", as in:
select sum(Total_Coupon_To_Be_Used) from (
SELECT dtc.coupon_type_company_name,
count(*) * dtc.coupon_type_company_coupon_amount as 'Total_Coupon_To_Be_Used',
dtc.coupon_type_company_coupon_months_combinable
FROM [dbo].[coupon_type_Company_User] dtcu
JOIN coupon_type_Company dtc ON dtcu.coupon_type_Company_ID = dtc.id
JOIN person p ON dtcu.userID = p.userID
WHERE coupon_type_company_coupon_is_combinable = 1
or coupon_type_company_has_coupon = 1
and dtc.companyID = 1081
AND p.is_active = 1
GROUP BY
dtc.coupon_type_company_name,dtc.coupon_type_company_coupon_amount,
dtc.coupon_type_company_coupon_months_combinable
) x

SQL Case statement how to get value regardless of other results

Here is my statement:
SELECT
CASE
WHEN #UserRole = 1 THEN 1
ELSE 0
END AS [CanEdit],
F.FundingStreamName
FROM FundingStream AS F
LEFT JOIN Projects AS P ON P.FundingStream = F.FundingStreamID
WHERE ProjectNumber = #ProjectNumber
I noticed if FundingStreamID is null, the case statement will return nothing as well, how can I get the case statement to execute regardless if there is a funding stream or not? Thanks.
I think the problem is that your where clause is "undoing" your left outer join. Try moving the condition to the on clause:
SELECT (CASE WHEN #UserRole = 1 THEN 1
ELSE 0
END) AS [CanEdit],
F.FundingStreamName
FROM FundingStream F LEFT JOIN
Projects P
ON P.FundingStream = F.FundingStreamID AND
P.ProjectNumber = #ProjectNumber ;
Using #MicSim answer:
SELECT
CASE
WHEN #UserRole = 1 THEN 1
ELSE 0
END AS [CanEdit],
F.FundingStreamName
FROM FundingStream AS F
RIGHT JOIN Projects AS P ON P.FundingStream = F.FundingStreamID
WHERE ProjectNumber = #ProjectNumber
Thanks again for the help!