To query empty fields I have seen this answer:
Postgresql, select empty fields
(unfortunately I don't have enough reputation points to answer #wildplasser on that post, so here we go)
Wildplasser's answer:
SELECT mystr, mystr1
FROM mytable
WHERE COALESCE(mystr, '') = ''
OR COALESCE(mystr1, '') = ''
;
I am not sure I get the COALESCE method, but it also works for me this way (specific for my string data type):
SELECT mystr, mystr1
FROM mytable
WHERE mystr = '' ;
My questions are:
Does COALESCE work for any data type?
Is there any better way to query empty strings? i.e., column_value = ' '
First you need to understand the difference between NULL and "empty".
NULL is the absence of a value. Any (or at least almost any) data type can be NULL. When you have a column of type integer, and you don't want to put a value in that field, you put NULL.
"Empty" is a string/text concept. It's a string with an empty value, i.e. ''. A text field with an empty string contains a value: the empty string. It is not the same as containing NULL, i.e. no value. Other data types e.g. integer, boolean, json, whatever, can't have an empty string.
Now to COALESCE. That function works on any data type, and basically it returns the first not-NULL result of its arguments. So COALESCE(NULL, TRUE) returns TRUE because the first argument is NULL; COALESCE(FALSE, TRUE) returns FALSE because the first argument is not NULL; and COALESCE(NULL, NULL) returns NULL because there are no not-NULL arguments.
So, COALESCE(field, '') returns the value of field if it's not NULL, and otherwise returns an empty string. When used in COALESCE(field, '') = '' when trying to find any rows where field is "empty", this is basically saying "if field is NULL then use an empty string in its place, then see if it equals an empty string". This is because NULL and an empty string are not equivalent, and "you" are trying to find any rows where fields are NULL or empty.
In your version of the query, where you just do field = '', that will ONLY return results where field is actually an empty string, not where field is NULL. Which behaviour you desire is up to you.
With COALESCE you will get NULL values too in the first query.
1- In Postgresql, you can't mix datatype example here, but you can use the function to_char to mix values
2- I don't understand your question
I think based on the definition of coalesce itself as
"The COALESCE() function returns the first non-null value in a list."
means that it work for any data type
I don't really understand the question but i think yes its already the most efficient way to make empty string
Related
A scenario where the variable tempMID of type string containing value "338715618884", checks if it contains "" or not. It is returning true. Why is this happening? in my understanding, this shouldn't return true.
That's documented:
String.Contains returns true if the value parameter occurs within
this string, or if value is the empty string (""); otherwise, false.
So it's working as expected. The language designer have decided that an empty string is contained in every existing string, which makes sense to me.
If I have a string for example:
"this.is.a.string.and.I.need.the.last.part"
I am trying to get the last part of the string after the last ".", which in this case is "part"
How to I achieve this?
One way I tried was to split the string on ".", I get a array back, but then I don't know how to retrieve the last item in the array.
| extend ToSplitstring = split("this.is.a.string.and.I.need.the.last.part", ".")
gives me:
["this", "is","a","string","and","I","need","the","last", "part"]
and a second try I have tried this:
| extend ToSubstring = substring(myString, lastindexof(myString, ".")+1)
but Kusto do not have a function of lastindexof.
Anyone with tips?
you can access the last member of the array using a negative index -1.
e.g. this:
print split("this.is.a.string.and.I.need.the.last.part", ".")[-1]
returns a single table, with a single column and a single record, with the value part
You can try the code below, and feel free to change it to meet your need:
let lastIndexof = (input:string, lookup: string) {
indexof(input, lookup, 0, -1, countof(input,lookup))
};
your_table_name
| extend ToSubstring = substring("this.is.a.string.and.I.need.the.last.part", lastIndexof("this.is.a.string.and.I.need.the.last.part", ".")+1)
Set timeVc=timeVw.Allentries
Set tobeDeleted=timeVw.Getalldocumentsbykey("", true)
Call tobeDeleted.removeall(True)
Just now want to confirm what is the meaning of getalldocumentbykey with empty string
GetAllDocumentsByKey with an empty string as first parameter returns an empty collection.
If you want to get all documents with an empty value in view's first sorted column then change the formula of your first sorted column to
#If(YourFieldName = ""; " "; YourFieldName)
It has a space instead of an empty string now.
Set tobeDeleted=timeVw.Getalldocumentsbykey(" ", true)
returns all those documents then.
I have this strange problem. i have a table with 10 columns of type character varying.
I need to have a function that searches all records and returns the id of the record which has all strings. Lets say records:
1. a,b,c,d,e
2. a,k,l,h
3. f,t,r,e,w,q
if i call this function func(a,d) it should return 1, if i call func(e,w,q) its should return 3.
The function is
CREATE OR REPLACE FUNCTION func(ma1 character varying,ma2 character varying,ma3 character varying,ma4 character varying)
DECLARE name numeric;
BEGIN
SELECT Id INTO name from Table WHERE
ma1 IN (col1,col2,col3,col4) AND
ma2 IN (col1,col2,col3,col4) AND
ma3 IN (col1,col2,col3,col4) AND
ma4 IN (col1,col2,col3,col4);
RETURN name;
END;
It's working 90% of the time, the weird problem is that some rows are not found.
Its not uppercase or lowercase problem.
What can be wrong, its version 9.1 on 64 bit win 7. I feel its like encoding or string problem but i can't see where and what.
//Ok i found the problem, it has to do with all column, if all 24 columns are filled in then its not working ?? but why ? are there limitations becouse there are 24 columns that i must compare with//
Can someone help me plz.
thanks.
The problem is (probably) that some of your columns have nulls.
In SQL, any equality comparison with a null is always false. This extends to the list of values used with the IN (...) condition.
If any of the values in the list are null, the comparison will be false, even if the value being sought is in the list.
The work-around is to make sure no values are null. which unfortunately results in a verbose solution:
WHERE ma1 IN (COALESCE(col1, ''), COALESCE(col2, ''), ...)
I suspect Bohemian is correct that the problem is related to nulls in your IN clauses. An alternative approach is to use Postgres's array contained in operator to perform your test.
where ARRAY[ma1,ma2,ma3,ma4] <# ARRAY[col1,col2,...,colN]
I am rolling up a huge table by counts into a new table, where I want to change all the empty strings to NULL, and typecast some columns as well. I read through some of the posts and I could not find a query, which would let me do it across all the columns in a single query, without using multiple statements.
Let me know if it is possible for me to iterate across all columns and replace cells with empty strings with null.
Ref: How to convert empty spaces into null values, using SQL Server?
To my knowledge there is no built-in function to replace empty strings across all columns of a table. You can write a plpgsql function to take care of that.
The following function replaces empty strings in all basic character-type columns of a given table with NULL. You can then cast to integer if the remaining strings are valid number literals.
CREATE OR REPLACE FUNCTION f_empty_text_to_null(_tbl regclass, OUT updated_rows int)
LANGUAGE plpgsql AS
$func$
DECLARE
_typ CONSTANT regtype[] := '{text, bpchar, varchar}'; -- ARRAY of all basic character types
_sql text;
BEGIN
SELECT INTO _sql -- build SQL command
'UPDATE ' || _tbl
|| E'\nSET ' || string_agg(format('%1$s = NULLIF(%1$s, '''')', col), E'\n ,')
|| E'\nWHERE ' || string_agg(col || ' = ''''', ' OR ')
FROM (
SELECT quote_ident(attname) AS col
FROM pg_attribute
WHERE attrelid = _tbl -- valid, visible, legal table name
AND attnum >= 1 -- exclude tableoid & friends
AND NOT attisdropped -- exclude dropped columns
AND NOT attnotnull -- exclude columns defined NOT NULL!
AND atttypid = ANY(_typ) -- only character types
ORDER BY attnum
) sub;
-- RAISE NOTICE '%', _sql; -- test?
-- Execute
IF _sql IS NULL THEN
updated_rows := 0; -- nothing to update
ELSE
EXECUTE _sql;
GET DIAGNOSTICS updated_rows = ROW_COUNT; -- Report number of affected rows
END IF;
END
$func$;
Call:
SELECT f_empty2null('mytable');
SELECT f_empty2null('myschema.mytable');
To also get the column name updated_rows:
SELECT * FROM f_empty2null('mytable');
db<>fiddle here
Old sqlfiddle
Major points
Table name has to be valid and visible and the calling user must have all necessary privileges. If any of these conditions are not met, the function will do nothing - i.e. nothing can be destroyed, either. I cast to the object identifier type regclass to make sure of it.
The table name can be supplied as is ('mytable'), then the search_path decides. Or schema-qualified to pick a certain schema ('myschema.mytable').
Query the system catalog to get all (character-type) columns of the table. The provided function uses these basic character types: text, bpchar, varchar, "char". Only relevant columns are processed.
Use quote_ident() or format() to sanitize column names and safeguard against SQLi.
The updated version uses the basic SQL aggregate function string_agg() to build the command string without looping, which is simpler and faster. And more elegant. :)
Has to use dynamic SQL with EXECUTE.
The updated version excludes columns defined NOT NULL and only updates each row once in a single statement, which is much faster for tables with multiple character-type columns.
Should work with any modern version of PostgreSQL. Tested with Postgres 9.1, 9.3, 9.5 and 13.