Optional conditions in postgreSQL query - sql

I need to create a procedure with optional arguments and use them only if they are not null
My current query looks like:
SELECT * FROM sth WHERE
(arg1 IS NULL OR sth.c1 = arg1) AND
(arg2 IS NULL OR sth.c2 = arg2) AND
(arg3 IS NULL OR sth.c3 > arg3) AND
(arg4 IS NULL OR sth.c4 < arg4)
I'm thinking of a way to make it look better / shorter. My first shot is:
SELECT * FROM sth WHERE
COALESCE(sth.c1 = arg1, 't') AND
COALESCE(sth.c2 = arg2, 't') AND
COALESCE(sth.c3 > arg3, 't') AND
COALESCE(sth.c4 < arg4, 't');
but I'm not sure if this looks any better. Do you know any useful tricks for this?

Keep it the way it is. Using coalesce will prevent the query planner from doing its job properly, and you'll end up with sucky query plans.
Best I'm aware, the following expressions will use a btree index:
col = 'val'
col is null
The following expressions will not use a btree index:
col is [not] 'val'
(col = 'val') is [not] <true | false | null>
col is [not] distinct from 'val'
coalesce(col, 'val') = 'val'
coalesce(col = 'val', <true | false | null>)

Ok, I think that this query is the best idea for this purpose
SELECT * FROM sth WHERE
NOT (sth.c1 = arg1) IS FALSE AND
NOT (sth.c2 = arg2) IS FALSE AND
NOT (sth.c3 > arg3) IS FALSE AND
NOT (sth.c4 < arg4) IS FALSE;
it doesn't use any functions so the query planner should work fine just as before
it just uses simple expressions where:
1.
true = true // true
true = false // false
true = null // null
2.
false is false // true
true is false // false
null is false // false
3.
not true // false
not false // true
so it will return true if expression is true OR null

Related

How to return a column by checking multiple column with True and False without if statements

How to get this desired output without using if statements ? and checking row by row
import pandas as pd
test = pd.DataFrame()
test['column1'] = [True, True, False]
test['column2']= [False,True,False]
index column1 column2
0 True False
1 True True
2 False False
desired output:
index column1 column2 column3
0 True False False
1 True True True
2 False False False
Your help is much appriciated.
Thank you in advance.
Use DataFrame.all for test if all values are Trues:
test['column3'] = test.all(axis=1)
If need filter columns add subset ['column1','column1']:
test['column3'] = test[['column1','column1']].all(axis=1)
If want test only 2 columns here is possible use & for bitwise AND:
test['column3'] = test['column1'] & test['column1']

SQL Database Systems

I have three Boolean Attributes in my Relation and I want only one of them to have true value or the table should give an error. How Can I do that?
You can use a check constraint, if your DBMS supports them (most of them do). In it you check, that exactly one of the flags is true. For that you can use a Boolean expression.
CREATE TABLE elbat
(...
CHECK (flag1 = true
AND flag2 = false
AND flag3 = false
OR flag1 = false
AND flag2 = true
AND flag3 = false
OR flag1 = false
AND flag2 = false
AND flag3 = true));
(Just to get the idea, syntax may vary from DBMS to DBMS.)
You can use a check constraint for that.
create table some_table
(
flag1 boolean not null,
flag2 boolean not null,
flag3 boolean not null,
constraint only_one_true
check ( (flag1,flag2,flag3) IN ( (true, false, false),
(false, true, false),
(false, false, true)) )
);
The above is standard SQL.
Some DBMS system also allow casting a boolean to a number representing 0 or 1 in that case you can just add them and the sum must be equal to 1 (ensuring that exactly one flag is set to true)
create table some_table
(
flag1 boolean not null,
flag2 boolean not null,
flag3 boolean not null,
constraint only_one_true
check ( cast(flag1 as integer) +
cast(flag2 as integer) +
cast(flag3 as integer) = 1 )
);

Pandas New Variable Based On Multiple Conditions

I have spent two days searching, any help would be appreciated.
Trying to create c_flg based on values in other columns.
a_flg b_flg Count c_flg (Expected Output)
False True 3 False
True False 2 False
False False 4 True
a_flg & b_flg are strs, Count is an int
Approaching from two angles, neither successful.
Method 1:
df['c_flg'] = np.where((df[(df['a_flg'] == 'False') &
(df['b_flg'] == 'False') &
(df['Count'] <= 6 )]), 'True', 'False')
ValueError: Length of values does not match length of index
Method 2:
def test_func(df):
if (('a_flg' == 'False') &
('b_flg' == 'False') &
('Count' <= 6 )):
return True
else:
return False
df['c_flg']=df.apply(test_func, axis=1)
TypeError: ('unorderable types: str() <= int()', 'occurred at index 0')
Very new to the Python language, help would be appreciated.
If I understand your problem properly then you need this,
df['c_flg']=(df['a_flg']=='False')&(df['b_flg']=='False')&(df['Count']<=6)
df['c_flg']=(df['a_flg']==False)&(df['b_flg']==False)&(df['Count']<=6)#use this if 'x_flg' is boolean
Output:
a_flg b_flg Count c_flg
0 False True 3 False
1 True False 2 False
2 False False 4 True
Note: For this problem you really don't need numpy, pandas itself can solve this without any problem.
I believe np.where is not necessary, use ~ for invert boolean mask and chain & for bitwise AND:
print (df.dtypes)
a_flg bool
b_flg bool
Count int64
dtype: object
df['c_flg'] = ~df['a_flg'] & ~df['b_flg'] & (df['Count'] <= 6)
print (df)
a_flg b_flg Count c_flg
0 False True 3 False
1 True False 2 False
2 False False 4 True

Return True if specific value exists in table - sql

I want to create an SQL query that will return True if a specific value exists in a specific column; if not, then it will return False.
I know that I can create something like 'SELECT something FROM somewhere WHERE something'. In this case I don't want to select anything, just to check.
My question is how can I do it.
You can use the IIf function:
SELECT IIf(something = 'Some value', True, False) FROM somewhere;
In Access, you can use a DCount expression to count the number of rows where your something field contains 'some value'. Here is an example copied from the Immediate window:
Debug.Print DCount("*", "somewhere", "something='some value'")
1
Debug.Print DCount("*", "somewhere", "something='BOGUS'")
0
You could adapt that to give you True when the count is greater than zero or False for count of zero:
Debug.Print (DCount("*", "somewhere", "something='some value'") > 0)
True
Debug.Print (DCount("*", "somewhere", "something='BOGUS'") > 0)
False
If you want to do it from a query, this one will return -1 for True and zero for False:
SELECT (DCount("*", "somewhere", "something='some value'") > 0) AS value_exists;
Or you could use a Format expression to display those values as strings: "True"; or "False":
SELECT Format(DCount("*", "somewhere", "something='some value'") > 0, 'True/False') AS value_exists;
As the name implies, DLookup is for this:
SomevalueExists = Not IsNull(DLookup("Id", "somewhere", "somefield = somevalue"))
try this:
select case when x is null then false else true end
from (select max(somecol) x
from sometable
where somecol = somevalue) a
just use
select count(*) from tableName where columnName = '$variableInput';
if you plan on reusing this you might as well make it a prepared statement that you can call upon through whichever interface you design to work with your database. If the returned value is greater than zero you know it to be true, for instance
if(preparedStatement($variableInput)>0)
{
$flag = true;
}
else
{
$flag = false;
}

JPA Query for toggling a boolean in a UPDATE

SQL version works okay and I can toggle the boolean called bar ...
mysql> update Foo set bar = ! bar WHERE id IN (1, 7, 13);
Query OK, 3 rows affected (0.02 sec)
Is there a easy JPA Query equivalent, I tried
final Set<Integer> ids;
final Query query = em.createQuery("UPDATE " + Foo.class.getName()
+ " a set bar= !bar"
+ " where a.id in :ids");
query.setParameter("ids", ids);
query.executeUpdate();
The above gives a org.hibernate.QueryException.
In my entity :
#Column(columnDefinition = "INTEGER", nullable = false)
private boolean bar;
Any ideas on the JPA syntax ?
That can be done with the case expression:
UPDATE FOO a
SET a.bar =
CASE a.bar
WHEN TRUE THEN FALSE
ELSE TRUE END
WHERE a.id in :ids
For nullable Boolean bit more is needed:
UPDATE FOO a
SET a.bar =
CASE a.bar
WHEN TRUE THEN FALSE
WHEN FALSE THEN TRUE
ELSE a.bar END
WHERE a.id in :ids