Where clause with a conditional condition - sql

Case: I have a stored procedure in where I got all the information of a table.
I have 2 parameters in order to set the Where clause but one of those could be
0.
Question: How do I do a Case When or an If in my Where clause depending on my parameter value?
I want to apply the where clause only if the value is different from 0
if is 0 I don't want to do it.
Code:
#ID_ORDER,
#ID_SUPPLIER
Select *
From Orders ord
where #ID_SUPPLIER = ord.ID_SUPPLIER
AND CASE WHEN #ID_ORDER = 0 THEN ord.ID_ORDER = #ID_ORDER END

You don't. You just use and and or:
select *
from Orders ord
where ord.ID_SUPPLIER = #ID_SUPPLIER) and
(ord.ID_ORDER = #ID_ORDER or #ID_ORDER = 0);
Note that the logic you are attempting is backwards. This only applies the filter on id_order when the value is not 0.

Related

A subquery within a CASE Statement

So I'm trying to put a subquery within a CASE statement. The subquery itself is working fine, but if I put it in another code it can't process. What can I do best to solve?
CASE WHEN dbo.T1.TYPE = 0
THEN dbo.Data.QTY * dbo.Data.SALESPRICE
ELSE
CASE WHEN dbo.T1.TYPE = 1
THEN dbo.Data.QTY *
(
SELECT dbo.Data.ID,
CASE WHEN SUM(dbo.Data.QTY) = 0
THEN SUM(dbo.Data.SALESPRICE)
ELSE SUM(dbo.Data.SALESPRICE) / SUM(dbo.Data.QTY)
END AS REVph
FROM dbo.Data LEFT OUTER JOIN
dbo.T1ON dbo.Data.ID = dbo.T1.ID
WHERE (dbo.T1.TYPE = 1)
GROUP BY dbo.Data.ID
)
ELSE 0
END
END
You are using a subquery in a context where a single value is allowed. Such a subquery is called a scalar subquery.
However, the subquery is returning more than one column. That is not allowed. A scalar subquery can only return one column and at most one row.
Your question is rather unclear on what you want to accomplish, so I can only explain the problem that you are having.

IF / Case statment in SQL

I have a column where I have 0 or 1. I like to do the following set up:
If 0 than put / use the Region_table (here I have regions like EMEA, AP,LA with finished goods only) and when it 1 then put / use the Plant_table (here I have plants with non-finished goods) data's.
I tried to write it in 2 different statements but it is not good:
,Case
when [FG_NFG_Selektion] = '0' Then 'AC_region'
End as 'AC_region'
,Case
when [FG_NFG_Selektion] = '1' Then 'AC_plant'
End as 'AC_plant'
I'm not 100% clear on what you're looking for, but if you want to get data from different tables based on the value in the [FG_NFG_Selektion] field, you can do something like this:
SELECT
CASE
WHEN [FG_NFG_Selektion] = '0' THEN r.some_col -- If 0, use value from "region" table
WHEN [FG_NFG_Selektion] = '1' THEN p.some_col -- If 1, use value from "plant" table
END AS new_field
FROM MyTable t
LEFT JOIN AC_region r ON t.pk_col = r.pk_col -- get data from "AC_region" table
LEFT JOIN AC_plant p ON t.pk_col = p.pk_col -- get data from "AC_plant" table
;
If [FG_NFG_Selektion] is a numeric field, then you should remove the single quotes: [FG_NFG_Selektion] = 0.
I would strongly recommend putting the conditions in the ON clauses:
SELECT COALESCE(r.some_col, p.some_col) as som_col
FROM t LEFT JOIN
AC_region r
ON t.pk_col = r.pk_col AND
t.FG_NFG_Selektion = '0' LEFT JOIN
AC_plant p
ON t.pk_col = p.pk_col AND
t.FG_NFG_Selektion = '1';
Why do I recommend this? First, this works correctly if there are multiple matches in either table. That is probably not an issue in this case, but it could be in others. You don't want to figure out where extra rows come from.
Second, putting the conditions in the ON clause allows the optimizer/execution engine to take advantage of them. For instance, it is more likely to use FG_NFG_Selektion in an index.

Update column within CASE statement with results of a subquery postgres

I need to update a column based on the results of a subquery. If the subquery returns results for that column then the columns must be updated, is the query returns no results for that column then I need to update with 0.
I do not know where to place the subquery and how to combine it with the CASE statement. This is what I thought but the syntax is not correct. Can anybody help please?
(SELECT datazones.ogc_fid, count(*) as total
FROM suppliersnew suppliers, datazone_report_resupply datazones
WHERE St_contains(datazones.geom, suppliers.geometry) AND (suppliers.status = 'Under construction' OR
suppliers.status = 'Unknown' OR suppliers.status = 'Operational') GROUP by datazones.ogc_fid ORDER BY total ASC) sources
UPDATE datazone_report_resupply
SET es_actual =
CASE
WHEN datazone_report_resupply.ogc_fid = sources.ogc_fid THEN sources.total
ELSE 0
END
The query is a little hard to follow, because the aggregation is on the outer column (this is unusual). However, you don't need aggregation or order by. You only seem to care whether a row exists.
I think the logic is:
UPDATE datazone_report_resupply r
SET es_actual =
(CASE WHEN EXISTS (SELECT 1
FROM suppliersnew s
WHERE St_contains(r.geom, s.geometry) AND
s.status IN ('Under construction', 'Unknown', 'Operational')
)
THEN 1 ELSE 0
END);

Gettin a value from a table and using in the same query

SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo != h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = 1
I'm trying to figure out if there's a possibility to get the h.cd_turnovalue from another table and use in the same query, beacuse this value is gonna be variable. So, I'd have to get this value from a query, then pass the value to PHP and do another query with this value. Is there a way to do that in the same query?
There's a table called turmas(codigo, cd_turno). I'll have the codigovalue, in this case HTJ009, and I'd like to select the cd_turno value.
Query used to get the value:
SELECT cd_turno FROM turmas WHERE codigo='HTJ009'
You can use a subquery, like so:
SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo != h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = (SELECT cd_turno FROM turmas WHERE codigo='HTJ009')
In this case, remember that it is important for the subquery to return only one result, otherwise you'll encounter an error. If you do see such an error, you may have to tweak the subquery to ensure only one result is returned.
Check this out for Postgres subquery documentation
SELECT (h.horario), h.codigo
FROM horarios as h
JOIN horario_turma as h_t
ON(h.codigo = h_t.cd_horario)
WHERE h_t.cd_turma = 'HTJ009'
AND h_t.cd_dia = 2
AND h.cd_turno = 1 and h_t.cd_horario is null

group by clause issue

I have written a query in access and now I am trying to write the same in SQL Server I am getting following error:
Msg 164, Level 15, State 1, Procedure OQRY_STEP_1_1, Line 15
Each GROUP BY expression must contain at least one column that is not an outer reference.
My SQL Query is as follows:
SELECT
ns11.SYS_ID,
ns11.SUB_NET_ID,
ns11.TEMP_ID,
ns11.EQ_ID,
ns11.NODE_NAME,
ns11.EQ_NAME,
ns11.VAR_NAME,
ns11.VAR_SET,
ns11.VAR_SUBSET,
ns11.EQ_TYPE,
ns11.RHS_RELN,
ns11.RHS_OBJECT,
ns11.EQ_TP_OFFSET,
ns11.RHS_TP_OFFSET,
ns11.RETAIN,
nmte.RHS_VAR_SET,
nmte.RHS_VAR_SUBSET,
nmte.RHS_VAR_NAME,
0 AS RHS_VAR_TYPE,
CASE
WHEN [asp].[VALUE] = NULL THEN 0
ELSE [asp].[VALUE]
END RHS_VALUE
INTO ##OT_STEP_1_1
FROM (##NT_STEP_1_1 ns11
INNER JOIN ##NT_MASTER_TEMP_EQUATION nmte
ON (ns11.SYS_ID = nmte.SYS_ID)
(ns11.SUB_NET_ID = nmte.SUB_NET_ID)
AND (ns11.TEMP_ID = nmte.TEMP_ID)
AND (ns11.EQ_ID = nmte.EQ_ID)
AND (ns11.NODE_NAME = nmte.NODE_NAME)
AND (nmte.SYS_ID = ns11.SYS_ID)
AND (nmte.SUB_NET_ID = ns11.SUB_NET_ID))
LEFT JOIN AMST_SIM_PAR asp ON
(nmte.SYS_ID = asp.SYS_ID)
AND (nmte.SUB_NET_ID = ns11.SUB_NET_ID)
AND (nmte.RHS_VAR_NAME = asp.VAR_NAME)
GROUP BY
ns11.SYS_ID,
ns11.SUB_NET_ID,
ns11.TEMP_ID,
ns11.EQ_ID,
ns11.NODE_NAME,
ns11.EQ_NAME,
ns11.VAR_NAME,
ns11.VAR_SET,
ns11.VAR_SUBSET,
ns11.EQ_TYPE,
ns11.RHS_RELN,
ns11.RHS_OBJECT,
ns11.EQ_TP_OFFSET,
ns11.RHS_TP_OFFSET,
ns11.RETAIN,
nmte.RHS_VAR_SET,
nmte.RHS_VAR_SUBSET,
nmte.RHS_VAR_NAME,
0,
CASE
WHEN [asp].[VALUE] = NULL THEN 0
ELSE [asp].[VALUE]
END
ORDER BY
CASE
WHEN [asp].[VALUE] = NULL THEN 0
ELSE [asp].[VALUE]
END;
I am not sure why it is not taking 0 in the group by clause?
I think the GROUP BY ..., 0, ... is the issue here. Try removing that 0 from there. There is no point grouping by a constant.
Sidenote:
CASE WHEN [AMST_SIM_PAR].[VALUE] = NULL
THEN 0
ELSE [AMST_SIM_PAR].[VALUE]
END
should be be written with IS NULL instead of = NULL or as:
COALESCE( [AMST_SIM_PAR].[VALUE], 0 )
I think the constant '0' in your group by is the problem.
Are you using ANSI_NULLS? SQL-92 defines "= NULL" or "<> NULL" to always return false. Try changing "= NULL" to "IS NULL".
Also in your left join you have a criteria that doesn't match the outer table. The inner join already links SUB_NET_ID on those two tables so you can remove it from your left join.
Since you are not taking any aggregates, why not just use DISTINCT instead of repeating all that noise in the GROUP BY? Also the ORDER BY is not very useful because you are using SELECT INTO, which creates a new table, which by definition is an unordered set of rows. In order to get the data out of that table in the right "order" you should use an ORDER BY when you eventually select out of it. If you want the data optimized for joins or what have you after the table is created, create a clustered index after the SELECT INTO. Finally, why are you using ##global temp tables? You know that two users can't execute this code at the same time, right?
All that said, here is a much simpler and easier to read version:
SELECT DISTINCT
n.SYS_ID,
n.SUB_NET_ID,
n.TEMP_ID,
n.EQ_ID,
n.NODE_NAME,
n.EQ_NAME,
n.VAR_NAME,
n.VAR_SET,
n.VAR_SUBSET,
n.EQ_TYPE,
n.RHS_RELN,
n.RHS_OBJECT,
n.EQ_TP_OFFSET,
n.RHS_TP_OFFSET,
n.RETAIN,
te.RHS_VAR_SET,
te.RHS_VAR_SUBSET,
te.RHS_VAR_NAME,
RHS_VAR_TYPE = 0,
RHS_VALUE = COALESCE(a.VALUE, 0)
INTO ##OT_STEP_1_1
FROM ##NT_STEP_1_1 AS n
INNER JOIN ##NT_MASTER_TEMP_EQUATION AS te
ON n.SYS_ID = te.SYS_ID
AND n.SUB_NET_ID = te.SUB_NET_ID
AND n.TEMP_ID = te.TEMP_ID
AND n.EQ_ID = te.EQ_ID
AND n.NODE_NAME = te.NODE_NAME
AND te.SYS_ID = n.SYS_ID
AND te.SUB_NET_ID = n.SUB_NET_ID
LEFT OUTER JOIN dbo.AMST_SIM_PAR AS a
ON te.SYS_ID = a.SYS_ID
AND te.SUB_NET_ID = n.SUB_NET_ID
AND te.RHS_VAR_NAME = a.VAR_NAME;