Here is my psql query :
WITH myconstants (nb_pieces,nb_room,is_fiber,codes_insee) as (
values (0,0,false,('95018','75018'))
)
SELECT
*
FROM
on_plan_buy pbuy
INNER JOIN
card_fiche fiche
ON pbuy.uuid = fiche.ad_uuid
INNER JOIN
myconstants const
ON true
WHERE pbuy.code_insee IN ('95018','75018')
AND pbuy.price <= 99999999 AND pbuy.price >= 0
AND CASE WHEN const.nb_pieces = 0 THEN pbuy.piece > 0 ELSE pbuy.piece = const.nb_pieces END
AND CASE WHEN const.nb_room = 0 THEN pbuy.chambre > 0 ELSE pbuy.chambre = const.nb_room END
AND CASE WHEN const.is_fiber = false THEN true ELSE fiche.fiber = true END
LIMIT 100;
It works fine.
But i would like to use my constant:
WITH myconstants (nb_pieces,nb_room,is_fiber,codes_insee) as (
values (0,0,false,('95018','75018'))
)
SELECT
*
FROM
on_plan_buy pbuy
INNER JOIN
card_fiche fiche
ON pbuy.uuid = fiche.ad_uuid
INNER JOIN
myconstants const
ON true
WHERE pbuy.code_insee IN const.codes_insee
AND pbuy.price <= 99999999 AND pbuy.price >= 0
AND CASE WHEN const.nb_pieces = 0 THEN pbuy.piece > 0 ELSE pbuy.piece = const.nb_pieces END
AND CASE WHEN const.nb_room = 0 THEN pbuy.chambre > 0 ELSE pbuy.chambre = const.nb_room END
AND CASE WHEN const.is_fiber = false THEN true ELSE fiche.fiber = true END
LIMIT 100;
And now it doesn't works.
Any idea how to use correctly the const.codes_insee ?
Regards
You have created a record with ('95018','75018') for codes_insee where you would like to specify a set of values to search using the IN operator. However this operator does not work with this type. Instead, you can change the data type to an array, allowing you to add more filters in the future if you desire, and use the array functions. I've used array_position to determine if the value is in the array. See below
WITH myconstants (nb_pieces,nb_room,is_fiber,codes_insee) as (
values (0,0,false,string_to_array('95018,75018',','))
)
SELECT
*
FROM
on_plan_buy pbuy
INNER JOIN
card_fiche fiche
ON pbuy.uuid = fiche.ad_uuid
INNER JOIN
myconstants const
ON true
WHERE
array_position(const.codes_insee,cast(pbuy.code_insee as text)) > -1
AND pbuy.price <= 99999999 AND pbuy.price >= 0
AND CASE WHEN const.nb_pieces = 0 THEN pbuy.piece > 0 ELSE pbuy.piece = const.nb_pieces END
AND CASE WHEN const.nb_room = 0 THEN pbuy.chambre > 0 ELSE pbuy.chambre = const.nb_room END
AND CASE WHEN const.is_fiber = false THEN true ELSE fiche.fiber = true END
LIMIT 100;
Reference
Postgresql Array Functions
Instead of IN please try exists:
WITH myconstants (nb_pieces,nb_room,is_fiber,codes_insee) as (
values (0,0,false,('95018','75018'))
)
SELECT
*
FROM
on_plan_buy pbuy
INNER JOIN
card_fiche fiche
ON pbuy.uuid = fiche.ad_uuid
INNER JOIN
myconstants const
ON true
WHERE
pbuy.price <= 99999999 AND pbuy.price >= 0
AND CASE WHEN const.nb_pieces = 0 THEN pbuy.piece > 0 ELSE pbuy.piece = const.nb_pieces END
AND CASE WHEN const.nb_room = 0 THEN pbuy.chambre > 0 ELSE pbuy.chambre = const.nb_room END
AND CASE WHEN const.is_fiber = false THEN true ELSE fiche.fiber = true END
and exists
(
select 1 from myconstants where pbuy.code_insee = myconstants.codes_insee
)
LIMIT 100;
Related
this is my code:
SELECT SUM
(CASE
WHEN (dbo.EMBARQUE.EmbEst) = 0 THEN
0
WHEN (dbo.EMBARQUE.EmbEst) = 3 THEN
0
WHEN (dbo.EMBARQUE.EmbEst) = 6 THEN
0
WHEN (dbo.EMBARQUE.EmbEst) = 7 THEN
CASE
WHEN (SELECT COUNT (dbo.CUMPLIDO.CumpCod) from dbo.CUMPLIDO where dbo.CUMPLIDO.EmbCod = dbo.EMBARQUE.EmbCod and dbo.CUMPLIDO.CumpVol = 0) > 0 THEN
0
ELSE
dbo.EMBARQUE.EmbVol
END
ELSE
dbo.EMBARQUE.EmbVol
END) FROM dbo.EMBARQUE
You have a subquery inside sum(). That isn't allowed. This version uses a subquery to calculate the flag you want and then moves the filtering logic to the WHERE clause:
SELECT SUM(e.EmbVol)
FROM (SELECT e.*,
(CASE WHEN EXISTS (SELECT 1 FROM dbo.CUMPLIDO c WHERE c.EmbCod = e.EmbCod AND c.CumpVol = 0)
THEN 1 ELSE 0
END) as is_CumpVol_0
FROM dbo.EMBARQUE e
WHERE e.EmbEst NOT IN (0, 3, 6)
) e
WHERE e.EmbEst <> 7 OR is_CumpVol_0 = 0;
SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
(CASE
WHEN DATALENGTH(CostRule.ModelName) = 0
THEN
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
ELSE
CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
END
)
) AS MonoCost
I want to define my where statement depending on the datalength of CostRule.ModelName. But i got an error: Incorrect syntax near '='. in CostRule.Type = 1 and i got a error in the ELSE statement.
Must be like this:
...
WHERE
(DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR
(DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
The CASE-style from your query cannot work.
you can change your statement like this:
SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE CostRule.ColorType=1
AND CostRule.Type=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN 1 ELSE 2 END
AND CostRule.Manufacturer=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN Printer.ManufacturerId ELSE Printer.ModelName END
You can't use a CASE statement to define where conditions like that. It will be easier to just use some boolean logic
SELECT *
FROM your_table
WHERE (DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR (DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
There are some other things that could be removed (like CostRule.ColorType = 1 since it is the same in both branches) but I've left them in here to illustrate how to transform your CASE statement into a boolean logic set.
It looks like you would just need to change the WHERE statement:
It looks like you will just need to change your WHERE statement to use OR and remove the CASE Statement.
(SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
DATALENGTH(CostRule.ModelName) = 0
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
OR
DATALENGTH(CostRule.ModelName) <> 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
) AS MonoCost
I want to make a toggle request as defined there T-SQL: Using a CASE in an UPDATE statement to update certain columns depending on a condition
I did this :
Update capteur
join smartparking_reference on(smartparking_reference.id_capteur = capteur.id_capteur)
set (CASE WHEN capteur.valeur != 0 then capteur.valeur = 0 and last_value_date = now() END)
where smartparking_reference.id_ref = 3;
But always a syntax error. So what did i miss ?
Apparently you want to update capteur.valeur only when it is nonzero and set it to zero. Try this simpler statement:
MySql style
Update capteur
join smartparking_reference on(smartparking_reference.id_capteur = capteur.id_capteur)
set valeur = case when valeur = 0 then 1 else 0 end, last_value_date = now()
where smartparking_reference.id_ref = 3;
Sql Server style
Update capteur
set valeur = case when valeur = 0 then 1 else 0 end, last_value_date = getdate()
from smartparking_reference
where smartparking_reference.id_capteur = capteur.id_capteur
and smartparking_reference.id_ref = 3;
I also guess your update statement has the wrong syntax
UPDATE c
SET valeur = 0, last_value_date = now()
FROM capteur c
INNER JOIN smartparking_reference AS sr ON
sr.id_capteur = c.id_capteur
WHERE sr.id_ref = 3 and c.valeur != 0
UPDATE capteur
SET capteur.valeur=(
CASE
WHEN capteur.valeur != 0 THEN
0 ELSE 'another value'
END
),last_value_date = now ()
FROM capteur
INNER JOIN smartparking_reference ON
smartparking_reference.id_capteur = capteur.id_capteur
WHERE
smartparking_reference.id_ref = 3;
I have this Where clause
Select * From Student_Info si
Inner Join Certifications cc
Inner Join Cert_Earned ce
Where si.grad_date = #grad_date
AND cc.org_no = #org_no
but I need an additional AND that should be ignored if it turns out the value is false, I will want ALL certificates
AND cc.industrial = CASE WHEN #industrial = 0 THEN Do Nothing
Else #industrial
This would normally be expressed as:
AND (#industrial = 0 OR ccc.industrial = #industrial)
It sounds like you just want to add a predicate that does an OR between two different conditions
AND (#industrial = 0 or ccc.industrial = #industrial)
You can do something like this with CASE functions:
AND 1 = (CASE WHEN #industrial = 0 THEN 1
ELSE CASE WHEN cc.industrial = #industrial THEN 1 END
END)
or if cc.industrial is not nullable, then maybe:
AND cc.industrial = CASE WHEN #industrial = 0 THEN cc.industrial
Else #industrial END
I have these two case statements and can not for the life of me figure out how to combine them to show in a MSSQL view. Any help would be great.
CASE WHEN [ordertype] = '2' THEN [CommissionAmt1] * - 1 ELSE [CommissionAmt1] END
and
CASE WHEN (is_member('Buyer') = 1 OR is_member('CustomerService') = 1) THEN 0 ELSE CommissionAmt1 END
Just adding the first case to wherever the CommissionAmt1 is referenced in the second statement.
CASE WHEN (is_member('Buyer') = 1 OR is_member('CustomerService') = 1) THEN
0
ELSE
CASE WHEN [ordertype] = '2' THEN
[CommissionAmt1] * - 1
ELSE
[CommissionAmt1]
END
END
Or going the other way. It was hard to understand which way the calculation needs to be performed. The only hint was []
CASE WHEN [ordertype] = '2' THEN
(
CASE WHEN (is_member('Buyer') = 1 OR is_member('CustomerService') = 1) THEN
0
ELSE
CommissionAmt1
END
) * - 1
ELSE
CASE WHEN (is_member('Buyer') = 1 OR is_member('CustomerService') = 1) THEN
0
ELSE
CommissionAmt1
END
END
Either way, you would be able to save some calculations by sub querying the dependent value.
SELECT
*,
ValueWithDependant=CASE WHEN (Dependant>0) THEN (SomeValue / Dependant) ELSE NULL END
FROM
(
SELECT
X,Y,Z,
Dependant=CASE WHEN SomeValue=1 THEN 1 ELSE 0 END
FROM
SomeTable
)AS DETAIL