"\N" within a case when statement - sql

What is the best way to use a case when statement that employs a "\N" ? I have a column of State data in which a "\N" populates when no state exists (for foreign countries). I'm trying to write a smile case when statement that changes the \N's to "unknown" but am receiving a Error: Invalid string literal: "\N". Is there a way to get around this?
SELECT
STATE_REGION, case when STATE_REGION = "\N" then "unknown" else 'STATE_REGION' end as state_region_two
FROM xxx

Below is for BigQuery Standard SQL
#standardSQL
SELECT STATE_REGION,
CASE
WHEN STATE_REGION = "\\N" THEN "unknown"
ELSE 'STATE_REGION'
END AS state_region_two
FROM `project.dataset.table`
... yet another option is
WHEN STATE_REGION = r"\N" THEN "unknown"

Related

Write SELECT CASE Statement with PostgreSQL pg and Node JS

I am using a RESTful API with Node.js/Express and a PostgreSQL database ( PostgreSQL version is 12.4). I'm not using an ORM just straight SQL. I am trying to create a "SELECT CASE" statement but I keep running into errors. The error messages I am getting are "confirmed_member is not a column". Can anyone see what is wrong with my syntax here:
var query = ['SELECT *, CASE WHEN confirmed = true THEN "confirmed_member" ELSE "pending" END AS "status" FROM members WHERE groupid = $1']
try {
const member = await pool.query(query, [groupid]);
res.status(200).json(member.rows)
} catch (err) {
res.status(400).json({ message: err.message })
}
Note: The query works fine in Valentina DB.
EDIT: In response to answers below, I switched to double quotes because this was the error I was getting in the IDE when I used single quotes
Use single quotes for string literals in SQL. Some flavors of SQL (e.g. SQLite) also accept double quotes, but you should not rely on this behavior.
var query = ["SELECT *, CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS status FROM members WHERE groupid = $1"];
You need to use single quote for the literals as follows:
SELECT *,
CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS "status"
FROM members WHERE groupid = $1
For anyone who comes across the same issue: I got it working by enclosing the SQL statement in double quotes and escaping the double quotes for the column name.
var query = ["SELECT *, CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS \"status\" FROM members WHERE groupid = $1"]

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

Postgresql Syntax error at or near " THEN "

I'm trying to create a view in Postgresql , but when I run this code appears this error:
syntax error at or near " THEN "
CREATE OR REPLACE VIEW VW_MONITOR_DEVICE AS
SELECT
P.POSIZIONE_DEVICE_ID AS MONITOR_DEVICE_ID,
P.VALID AS VALID,
[...]
IF (VALID == FALSE THEN 'Valid' ELSE P.REASON_FOR_INVALID) AS DESCRIPTION,
[...]
FROM public.TA_POSIZIONI_DEVICE P
JOIN ...
TA_POSIZIONI_DEVICE
VALID (Boolean not null)
You should use CASE
The SQL CASE expression is a generic conditional expression, similar
to if/else statements in other programming languages
CASE WHEN condition THEN result
[WHEN ...]
[ELSE result]
END
So,
CREATE OR REPLACE VIEW VW_MONITOR_DEVICE AS
SELECT
P.POSIZIONE_DEVICE_ID AS MONITOR_DEVICE_ID,
P.VALID AS VALID,
[...]
CASE WHEN VALID = false THEN 'Valid'
ELSE P.REASON_FOR_INVALID
END AS DESCRIPTION,
[...]
FROM public.TA_POSIZIONI_DEVICE P
JOIN ...
you can use case
case when VALID = FALSE THEN 'Valid' ELSE P.REASON_FOR_INVALID end DESCRIPTION,
IF (VALID == FALSE) THEN 'Valid' ELSE P.REASON_FOR_INVALID END IF AS DESCRIPTION
Try this ! You've got a parenthensis issue in you condition

sqlite select where...and vs. case...when

I'm new to sqlite and have a populated database where I need to determine if any of the digital organisms in the database have a threshold level of fitness (fitness>=2) and are alive (live=1). I also need to exclude the indivID (the Primary Key) of the organism for whom I am trying to find a fit mate (indivID INTEGER PRIMARY KEY).
Below I tried the first line of code but it threw a SQL error:
[SQLITE_ERROR] SQL error or missing database (near "CASE": syntax
error).
However I know the error is in the SQL statment because other functions are successfully accessing the database.
SELECT indivID FROM population CASE fitness >=2 WHEN live = 1 AND indivID!=[specific individual] ELSE NULL END
I have tried this next line of code, which works but does not properly exclude the indivID of the specific individual:
SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]
I have three questions:
1) Where are my errors in the above statements
2) What is the difference between using "case...when" and "where...and" statements
3) It is possible and even probable on these queries that there may not be a "live=1" individual with high enough fitness (above 2) to qualify for the select statement, so will the outcome of both of these queries with no viable individual (if correctly written) then be null?
Thanks in advance for your help!
According to your first query, you seem to misunderstand the usage of case when. It's like an if for a single value. It's usually used to get the required value based on some column values, e.g.
SELECT CASE WHEN col>0 THEN 1 ELSE 0 END FROM table
However it can also be used for some nifty tricks on the condition, e.g.
SELECT col FROM table WHERE CASE WHEN some_param = 1 THEN col2 = 1 ELSE true END
This statement retrieves column col for rows where col2 = 1 if some input parameter is 1 or for all rows if input parameter is something else than 1.
Using WHERE ... AND checks the condition, e.g.
SELECT col FROM table WHERE col>0 AND col2=0
In your case, you're trying to select a null if no matching values are found. I don't think it's the right way of dealing with it. You should attempt to select what you're looking for and then check whether you got any rows back. You would essentially get to something like this:
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]");
if(rs.first()) {
//You have some data - loop over the resultset and retrieve it
}
else {
//There are no matches to your query
}
If you only want one match, then you can simplify this to
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual] LIMIT 1");
String name = rs.first() ? rs.getString(1) : null;
Note that I used index 1 for getString - but it may be whatever you need.
EDIT: If you're dealing with SQLite, then you have a single-direction-moveable resultset, therefore you need to change the above code slightly:
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual]");
if(!rs.isBeforeFirst()) {
//You have some data - loop over the resultset and retrieve it
}
else {
//There are no matches to your query
}
And, correspondingly,
ResultSet rs = stmt.executeQuery("SELECT [some column names] FROM [a database] WHERE fitness>=2 AND live=1 AND indivID!=[specific individual] LIMIT 1");
String name = !rs.isBeforeFirst() ? null : rs.getString(1) : null;;
Note the change of rs.first() to !rs.isBeforeFirst() and the reversal of the condition.

Conditional Where clauses in JasperReports

Let's say I want a JasperReport that lets the user filter on a date if they so wish. The SQL is as follows:
select * from foo where bar = $P{bar} and some_date > $P{some.date}
Now, I don't want to filter by some date if they didn't pass the date in. I found the following kludge that people use:
select * from foo where bar = $P{bar} $P!{some.date.fragment}
And the some.date.fragment parameter is defined with the following default:
($P{some.date} == null || $P{some.date}.equals("")) ? "" : "AND some_date >'" + new java.sql.Date($P{some.date}.getTime()).toString() + "'"
This is not working as the toString doesn't output the date in a format that my SQL server understands. I would like to have the conditional still use a prepared statement with the jdbc driver and toss the parameter in, I just want the prepared statement to be dependent on if the parameter is null or not. Can this be done?
Before you have used the $P!{} expression the JDBC-Driver does all formatting for you.
But if you use the $P!{} expression you have to format yourself.
Something like this should work:
(
$P{some.date} == null
?
""
:
"AND some_date >'" + (new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS")).format($P{some.date}) + "'"
)
Depending on your data type you have to customize dd.MM.yyyy HH:mm:ss.SSS.
If you don't want to use the $P!{} expression you can avoid it with the solution below.
I personally don't like this way. It also may cause a bad execution plan.
If don't want to use $P!{} because you worry about sql injection. It's needless as long your parameter $P{some.date} contains a safe data type like java.lang.Date.
Create a parameter. Let's call it ${is_null_pram} and add a default expression with param class Integer:
($P{some.date} == null ? 1 : 0)
Now you can query:
SELECT
*
FROM foo
WHERE
bar = $P{bar}
AND
(
some_date > $P{some.date}
OR 1 = $P{is_null_pram}
)
I think you can use the function:
$X{EQUAL, <column_name>, <parameter_name>}
It optimizes the query as you can see in this help page.
You can use this conditional statement
select *
from foo
where bar = $P{bar} and some_date > $P{some.date} or $P{some.date} is null