how to prevent converting the text into boolean by the use of when statement in postgresql? - sql

select fti.pa_serial_,fti.homeownerm_name,fti.ward_,fti.villagetole,fti.status,
ftrq.date_reporting, ftrq.name_of_recorder_reporting,
case
when fti.status='terminate' then ftrq.is_the_site_cleared ='1' end as is_the_site_cleared from fti join ftrq on ftrq.fulcrum_parent_id = fti.fulcrum_id
Here, is_the_site_cleared is text type of column which is converted into boolean by the when statement written and hence does not print as 1 and takes as true. I explicitly used print '1'. But this also did not work. My aim is to display '1' in the column 'is_the_site_cleared' when the value of fti.status='terminate'. Please help!!!

How about using integers rather than booleans?
select fti.pa_serial_, fti.homeownerm_name, fti.ward_,
fti.villagetole, fti.status, ftrq.date_reporting,
ftrq.name_of_recorder_reporting,
(case when fti.status = 'terminate' -- and ftrq.is_the_site_cleared = '1'
then 1 else 0
end) as is_the_site_cleared
from fti join
ftrq
on ftrq.fulcrum_parent_id = fti.fulcrum_id ;
From the description, I cannot tell if you want to include the condition ftrq.is_the_site_cleared = '1' in the when condition. But the idea is to have the then and else return numbers if that is what you want to see.

Related

Postgres SQL state: 22P02 - invalid input syntax for integer

I'm using a sql query to export a database from my company's program.
Everything seems to be fine till I change the date on the "where" statement with a previous one.
Please find below the code:
SELECT p."Index", p."PSN" || CAST(p."PNR"as int) AS ID,
p."PSN" AS Serie, cast(p."PNR"as int) AS Numar,
pr."PINDate" AS r_gdate,
CASE WHEN pr."AsigEID"='10' THEN pr."PrimSUM" ELSE
pr."PrimSUM"*valuta1."EXCValue" END AS r_prima_lei,
CASE WHEN pr."AsigEID"='2'
THEN pr."PrimSUM"
ELSE CASE WHEN pr."AsigEID"='10' THEN pr."PrimSUM"/valuta2."EXCValue"
ELSE pr."PrimSUM"*valuta1."EXCValue"/valuta2."EXCValue"
END
END AS r_prima_eur,
CASE WHEN pr."AsigEID"='10' THEN pr."AsigSUM" ELSE
pr."AsigSUM"*valuta1."EXCValue" END as r_sa_lei,
CASE WHEN pr."AsigEID"='2'
THEN pr."AsigSUM"
ELSE CASE WHEN pr."AsigEID"='10' THEN pr."AsigSUM"/valuta2."EXCValue"
ELSE pr."AsigSUM"*valuta1."EXCValue"/valuta2."EXCValue"
END
END AS r_sa_eur,
pr."AsigStart", pr."AsigEnd", risc."Code", plink."Index"
FROM "PolsRisc" AS pr
LEFT JOIN "Pols" as p ON p."Index" = pr."PID"
LEFT JOIN "Riscs" as risc ON pr."RID" = risc."Index"
LEFT JOIN "PRLNK" plink ON plink."PTID" = p."PTID" AND plink."RID" = risc."Index"
LEFT JOIN "EXCValues" valuta1 ON valuta1."AtDate" = pr."AsigStart" AND valuta1."EID" = pr."AsigEID"
LEFT JOIN "EXCValues" valuta2 ON valuta2."AtDate" = pr."AsigStart" AND valuta2."EID"='2'
WHERE pr."PINDate" > '2020-08-01' AND pr."IsRezil" = 'false';
When I'm using '2020-08-01' the query works well. When I try to change it to a previous one eg. '2010-01-01' a get an error:
ERROR: invalid input syntax for integer: ""
SQL state: 22P02
I was looking for a solution on the previous posts but I didn't manage to solve this issue.
It looks like it is returning "" or a null value into one of the columns you are using integer logic for. The date change is just filtering out the data that would crash it.
You may need to use coalesce to reassign the nulls as 0 and then cast it back into being an int
select
cast(coalesce(table.column, 0) as int) as result
from table
I would advice to read the chapter http://www.postgresql.org/docs/current/interactive/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
. It's a brief and informative read.The cause for the error message is that '' is an empty string that has no representation in a numeric type like integer

SQL to display a column value as a set value or null depending on status

below is the code I have written - what I want is when the status is equal to 'N' to display 'Export to WMS' in the column 'Export to WMS'.
If it has any other value than 'N' in the status, I want the column to still appear because some results will be at status 'N' but for those that aren't I want the value of that column to be blank.
select
m.display_order_number, m.record_create_date, l.lookup_description,m.wh_id,
m.client_code,m.order_type,m.order_date,m.UIN, m.ship_to_name,m.carrier,
(select DISTINCT 'Export to WMS'
from
t_3pl_order_master
where
status = 'N') AS "Export to WMS"
from
t_3pl_order_master m
INNER JOIN
t_3pl_lookup l on m.status = l.lookup_value AND l.lookup_type = 'Order Status';
Results I get are:
Where you can clearly see when the status is 'W' it still displays 'Export to WMS' but ideally I would want that to be blank and those with status 'N' to display 'Export to WMS'.
Hope you can help!
Use a case expression:
CASE WHEN status = 'N' THEN 'Export to WMS' END
in this way:
select m.display_order_number,
m.record_create_date,
l.lookup_description,
m.wh_id,
m.client_code,
m.order_type,
m.order_date,
m.UIN,
m.ship_to_name,
m.carrier,
CASE WHEN status = 'N' THEN 'Export to WMS' END AS "Export to WMS"
from t_3pl_order_master m
INNER JOIN t_3pl_lookup l on m.status = l.lookup_value AND l.lookup_type = 'Order Status';
see this link for details: https://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions004.htm
Need the ELSE in there to make it blank. Otherwise it will be null.
CASE WHEN status = 'N' THEN 'Export to WMS' ELSE ' ' END AS "Export to WMS"
If I read your post correctly just use the case statement to handle this.
I would highly recommend using the case expressions already described in other answers. But to explain why your attempt didn't work I'll give you a fix of sorts.
select
m.display_order_number, m.record_create_date, l.lookup_description,m.wh_id,
m.client_code,m.order_type,m.order_date,m.UIN, m.ship_to_name,m.carrier,
(
select distinct 'Export to WMS'
from t_3pl_order_master m2
where m.status = 'N' /* <<--- Difference is here */
) AS "Export to WMS"
from
t_3pl_order_master m inner join
t_3pl_lookup l on m.status = l.lookup_value AND l.lookup_type = 'Order Status';
The subquery as you wrote it will always return the single value "Export to WMS" as long as there is at least one row in the entire table where status = 'N'. What you needed to do was correlate (connect) the subquery to the outer query by referring to m.status rather than just status.
Note that it would then evaluate to a null as "blank". Use coalesce() to turn that into the empty string if that's actually necessary.
Now the truth is that this is a very roundabout way of getting what you wanted although clever in the sense that you used the syntax you already knew to piece something together that was pretty close.

How to give change working of having function dynamicaly on executing an sql statement?

I'm having a Sql code like as follows
Select a.ItemCode, a.ItemDesc
From fn_BOM_Material_Master('A', #AsOnDate, #RptDate, #BranchID, #CompID)a
Left Outer Join fn_INV_AsOnDate_Stock(#StockDate, #AsOnDate, #RptDate, #BranchID, #CompID, #Finyear)b
On a.ItemCode=b.ItemCode and b.WarehouseCode<>'WAP'
and a.BranchID=b.BranchID and a.CompID=b.COmpID
Where a.ItemNatureCode = 'F' and a.BranchID = #BranchID and a.CompID = #CompID
Group by a.ItemCode, a.ItemDesc
Having sum(b.CBQty)<=0
Here the problem is that im passing an "#ShowZeroStock" value as as bit if the "#ShowZeroStock" value is '1' then Having should not be validated or (i.e: All values from the table should be returned including zero)
So How to change the query based on passed bit value "#ShowZeroStock"
I can Use "If else " condition at the top and remove having in else part, but for a lengthy query i can't do the same.
Is this the logic you want?
Having sum(b.CBQty) <= 0 or #ShowZeroStock = 1

Conditional Sql in Daisy chained Query

I have one master table with all the IDs to each child table. The SQL statement looks like this...
SELECT Class.Descript
, Regulation.Descript AS Reg
, Compgroup.Descript AS Grouping
, Category.Descript AS Cat
, Exempt.Descript AS Exempt
, Reason.Descript AS Reasons
, COALESCE(ComponentRuleSet.NormalType, ComponentRuleSet.Supertype, '') AS Type
FROM ComponentRuleSet
LEFT OUTER JOIN Reason
ON ComponentRuleSet.ComponentCategoryID = Reason.ComponentCategoryID
LEFT OUTER JOIN Class
ON ComponentRuleSet.ComponentClassID = Class.ComponentClassID
LEFT OUTER JOIN Regulation
ON ComponentRuleSet.RegulationID = Regulation.RegulationID
LEFT OUTER JOIN Compgroup
ON ComponentRuleSet.ComplianceGroupID = Compgroup.ComplianceGroupID
LEFT OUTER JOIN Category
ON ComponentRuleSet.ComponentCategoryID = Category.ComponentCategoryId
LEFT OUTER JOIN Exempt
ON ComponentRuleSet.ExemptID = Exempt.ComponentExemptionID
WHERE (ComponentRuleSet.ComponentID = 38048)
The problem is that there are two fields in the ComponentRuleSet table called NormalType and Supertype. If either of those fields have a value, I need to display it in a column called Type. Yet, if neither have a value I need to display a Blank value in the Type column.
Any ideas?
---EDIT
Is my placement of COALESCE correct in the edited query? It is still returning errors.
--UPDATE
IMPORTANT: The type of both fields are boolean, I need to return the column name of the column that holds a TRUE value, and place that value in the TYPE column.
Use COALESCE for this field:
COALESCE(ComponentRuleSet.NormalType, ComponentRuleSet.Supertype, '') AS Type
COALESCE:
Returns the first nonnull expression among its arguments.
Following your comments as to the actual requirement, CASE is probably a better option:
CASE WHEN ComponentRuleSet.NormalType = 1 THEN 'NormalType'
WHEN ComponentRuleSet.Supertype = 1 THEN 'SuperType'
ELSE ''
END AS Type
Seeing your comments, perhaps a CASE expression will work:
select ...
, CASE WHEN ComponentRuleSet.NormalType is not null then 'NormalType'
WHEN ComponentRuleSet.Supertype is not null then 'SuperType'
ELSE ''
end as Type
UPDATE Since boolean values are just 1 for true and 0 for false, try this:
select ...
, CASE WHEN ComponentRuleSet.NormalType = 1 then 'NormalType'
WHEN ComponentRuleSet.Supertype = 1 then 'SuperType'
ELSE ''
end as Type

Modify Return Value of SELECT-Statement (TSQL) [Optimizing query]

Problem:
A Database collumn has a Tristate (0,1,2).
Each of the values are used serversidely.
The Clientcode (which cant be changed anymore) is only able to understand '0,1'.
In the Clients view '1' is identic with '2'. So I want to change the SQL Query in the Database to return '1', if the specific value is > 0.
My current Solution is combining 2 Selects (using UNION SELECT) with different WHERE-Clauses and returning '1' or '0' as static values. Now I'm looking for a solution to 'translate' the value within only ONE SELECT statement.
This is my current Solution:
SELECT
dbo.Nachricht.NachrichtID, dbo.Nachricht.Bezeichnung, '1' AS BetrifftKontoeinrichtung,
FROM dbo.Nachricht INNER JOIN dbo.AdditionalData
ON dbo.Nachricht.NachrichtID = dbo.AdditionalData.NachrichtID
WHERE (dbo.Nachricht.NachrichtID in ( 450,439 ))
AND dbo.AdditionalData.BetrifftKontoeinrichtung > 0
UNION SELECT
dbo.Nachricht.NachrichtID, dbo.Nachricht.Bezeichnung, '0' AS BetrifftKontoeinrichtung,
FROM dbo.Nachricht INNER JOIN dbo.AdditionalData
ON dbo.Nachricht.NachrichtID = dbo.AdditionalData.NachrichtID
WHERE (dbo.Nachricht.NachrichtID in ( 450,439 ))
AND dbo.AdditionalData.BetrifftKontoeinrichtung = 0
You can use a case statement, like this:
SELECT
dbo.Nachricht.NachrichtID, dbo.Nachricht.Bezeichnung,
CASE WHEN dbo.AdditionalData.BetrifftKontoeinrichtung = 0
THEN '0' ELSE '1'
END AS BetrifftKontoeinrichtung,
FROM dbo.Nachricht
INNER JOIN dbo.AdditionalData
ON dbo.Nachricht.NachrichtID = dbo.AdditionalData.NachrichtID
WHERE (dbo.Nachricht.NachrichtID in ( 450,439 ))
Looks like you need to use CASE. A decent tutorial here
http://www.databasejournal.com/features/mssql/article.php/3288921/T-SQL-Programming-Part-5---Using-the-CASE-Function.htm
See the worked example
If you just CAST(CAST(val AS BIT) AS INT) you will get integer 0 for 0 and integer 1 for everything else.