checking for boolean true / false result in postgresql query - sql

I am running the following sql query in my web app:
SELECT EXISTS (
SELECT id
FROM user
WHERE membership=1244)
i was expecting true (boolean data) as the result but I'm getting 't' or 'f' for false.
How do I get it to return to my lua code a standard boolean?
I found the following post:
Reading boolean correctly from Postgres by PHP
And so I tried to change my code to something like this:
SELECT EXISTS ::int (
SELECT id
FROM user
WHERE membership=1244)
or
SELECT ::INT (SELECT EXISTS (
SELECT id
FROM user
WHERE membership=1244))
But I'm getting a syntax error.
Can you tell the best way to handle this? Should I be casting the resulting 't' to a boolean somehow? or is there a way to tell postgresql to return true / false instead of 't'/'f'?
Thanks.

You are so close
SELECT EXISTS (SELECT id FROM user WHERE membership=1244)::int

Your first query do indeed return a boolean. A t is shown as the returned value of the query
select exists (select 1);
exists
--------
t
But if you check its type it is a boolean:
select pg_typeof(exists (select 1));
pg_typeof
-----------
boolean
You will have to check with the lua's postgresql driver manual how to properly handle it.

Try it with CASE
select
(case when exists (SELECT id FROM user WHERE membership = 1244)
then 1
else 0
end) as column;
my test fiddle

Your initial query is fine by itself:
SELECT id FROM user WHERE membership=1244
You just need to check if it returns a row or not.

Related

How to pass a string of column name as a parameter into a CREATE TABLE FUNCTION in BigQuery

I want to create a table function that takes two arguments, fieldName and parameter, where I can later use this function to create tables in other fieldName and parameter pairs. I tried multiple ways, and it seems like the fieldName(column name) is always parsed as a string in the where clause. Wondering how should I be doing this in the correct way.
CREATE OR REPLACE TABLE FUNCTION dataset.functionName( fieldName ANY TYPE, parameter ANY TYPE)
as
(SELECT *
FROM `dataset.table`
WHERE format("%t",fieldName ) = parameter
)
Later call the function as
SELECT *
from dataset.functionName( 'passed_qa', 'yes')
(passed_qa is a column name and assume it only has 'yes' and 'no' value)
I tried using EXECUTE IMMEDIATE, it works, but I just want to know if there's a way to approach this in a functional way.
Thanks for any help!
Good news - IT IS POSSIBLE!!! (side note: in my experience - i haven't had any cases when something was not possible to achieve in BigQuery directly or indirectly/workaround maybe with some few exceptions)
See example below
create or replace table function dataset.functionName(fieldName any type, parameter any type)
as (
select * from `bigquery-public-data.utility_us.us_states_area` t
where exists ( select true
from unnest(`bqutil.fn.json_extract_keys`(to_json_string(t))) key with offset
join unnest(`bqutil.fn.json_extract_values`(to_json_string(t))) value with offset
using(offset)
where key = fieldName and value = parameter
)
)
Now, when table function created - run below as see result
select *
from dataset.functionName('state_abbreviation', 'GU')
you will get record for GUAM
Then try below
select *
from dataset.functionName('division_code', '0')
with output
For details see:
https://cloud.google.com/bigquery/docs/reference/standard-sql/table-functions
A work-around can be to use a case statement to select the desired column. If any column is needed, please use the solution of Mikhail Berlyant.
Create or replace table function Test.HL(fieldName string,parameter ANY TYPE)
as
(
SELECT *
From ( select "1" as tmp, 2 as passed_qa) # generate dummy table
Where case
when fieldName="passed_qa" then format("%t",passed_qa)
when fieldName="tmp" then format("%t",tmp)
else ERROR(concat('column ',fieldName,' not found')) end = parameter
)

SELECT refering value to sub query

I am trying to get a random id value from my table. The condition is that the selected value must not exist for the same id and different language (language is lang field)
I do this:
SELECT id_v as p,cont FROM value_phrase WHERE lang=1 AND
NULL IN (SELECT cont FROM value_phrase WHERE id_v=p AND lang=2)
ORDER BY RAND() LIMIT 0,1
... but I do not get any results (It must be an error in my query, because there are many rows satisfying the desired condition.) How should I fix it?
-- SOLVED --
the solution is to use NOT EXISTS instead of NULL IN, and use table aliases to refer the first id_v into the sub query. This way (thanks to Mark Byers):
SELECT first.id_v, first.cont
FROM value_phrase AS
FIRST WHERE lang =1
AND NOT
EXISTS (
SELECT cont
FROM value_phrase
WHERE id_v = first.id_v
AND lang =2
)
ORDER BY RAND( )
LIMIT 0 , 1
If you want to check if a value does not exist, use NOT EXISTS.
AND NOT EXISTS (SELECT ... )
Your condition NULL IN (...) will never return anything, because a comparison with NULL always returns NULL and that is treated as "false" in a query condition.

SQLite IF Exists Clause

How to write IF EXISTS as shown in below query in SQLite? I read somewhere that IF clause doesn't exist in SQLite. What would be a better alternative for this?
if exists (select username from tbl_stats_assigned where username = 'abc' )
select 1 as uname
else
select 0 as uname
Just do it the standard SQL way:
select exists(
select 1
from tbl_stats_assigned
where username = 'abc'
);
Assuming of course that your 1 and 0 are actually boolean values (which SQLite represents with one and zero just like MySQL).
That should work in any SQL database and some even have special optimizations to support that idiom.

Postgresql case and testing boolean fields

First: I'm running postgresql 8.2 and testing my queries on pgAdmin.
I have a table with some fields, say:
mytable(
id integer,
mycheck boolean,
someText varchar(200));
Now, I want a query similary to this:
select id,
case when mycheck then (select name from tableA)
else (select name from tableB) end as mySpecialName,
someText;
I tried to run and get this:
ERROR: CASE types character varying and boolean cannot be matched
SQL state: 42804
And even trying to fool postgresql with
case (mycheck::integer) when 0 then
didn't work.
So, my question is: since sql doesn't have if, only case, how I'm suppose to do an if with a boolean field?
Your problem is a mismatch in your values (expressions after then and else), not your predicate (expression after when). Make sure that select name from tableA and select name from tableB return the same result type. mycheck is supposed to be a boolean.
I ran this query on PostgreSQL 9.0beta2, and (except for having to add from mytable to the SELECT statement as well as creating tables tableA and tableB), and it didn't yield any type errors. However, I get an error message much like the one you described when I run the following:
select case when true
then 1
else 'hello'::text
end;
The above yields:
ERROR: CASE types text and integer cannot be matched
I just ran this fine on PostgreSQL 8:
select id,
case when mycheck = true then (...)
else (...),
someText;

How to select an empty result set?

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I'm using a stored procedure in MySQL, with a CASE statement.
In the ELSE clause of the CASE ( equivalent to default: ) I want to select and return an empty result set, thus avoiding to throw an SQL error by not handling the ELSE case, and instead return an empty result set as if a regular query would have returned no rows.
So far I've managed to do so using something like:
Select NULL From users Where False
But I have to name an existing table, like 'users' in this example.
It works, but I would prefer a way that doesn't break if eventually the table name used is renamed or dropped.
I've tried Select NULL Where False but it doesn't work.
Using Select NULL does not return an empty set, but one row with a column named NULL and with a NULL value.
There's a dummy-table in MySQL called 'dual', which you should be able to use.
select
1
from
dual
where
false
This will always give you an empty result.
This should work on most DBs, tested on Postgres and Netezza:
SELECT NULL LIMIT 0;
T-SQL (MSSQL):
SELECT Top 0 1;
How about
SELECT * FROM (SELECT 1) AS TBL WHERE 2=3
Checked in myphp, and it also works in sqlite and probably in any other db engine.
This will probably work across all databases.
SELECT * FROM (SELECT NULL AS col0) AS inner0 WHERE col0 IS NOT NULL;
SELECT TOP 0 * FROM [dbo].[TableName]
This is a reasonable approach to constant scan operator.
SELECT NULL WHERE FALSE;
it works in postgresql ,mysql, subquery in mysql.
How about this?
SELECT 'MyName' AS EmptyColumn
FROM dual
WHERE 'Me' = 'Funny'
SELECT * FROM (SELECT NULL) WHERE 0
In PostgreSQL a simple
SELECT;
works. You won't even get any columns labeled 'unknown'.
Note however, it still says 1 row retrieved.