According to postgresql manual != means the same as <>. In reality, it doesn't seems to be the case:
psql=> select 1 where 1!=-1;
ERROR: operator does not exist: integer !=- integer
LINE 1: select 1 where 1!=-1;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
psql=> select 1 where 1<>-1;
?column?
----------
1
(1 row)
Is this a bug or this is an expected behavior that wasn't covered by the manual?
You need to write a space so that postgres knows, that it's a != operator and not !=-:
select 1 != -1;
Or you can put it in parentheses:
select 1!=(-1);
The SQL standard operator is <>, so it is a good habit to stick with it.
The reason for the behavior difference is explained in the documentation:
There are a few restrictions on your choice of [operator] name:
A multicharacter operator name cannot end in + or -, unless the name also contains at least one of these characters:
~ ! # # % ^ & | ` ?
For example, #- is an allowed operator name, but *- is not. This restriction allows PostgreSQL to parse SQL-compliant commands without requiring spaces between tokens.
Now since <> does not contain any of these characters, PostgreSQL knows that <>- cannot be an operator name, and there is no ambiguity in parsing.
Related
I tried to run the following query:
select * from table where regexp_like('^{{', text_field)
And got the following error:
too big number for repeat range
Thinking perhaps regexp_like is confusing { for the repeat count operator, I also tried the following variations:
select * from table where regexp_like('^\{\{', text_field)
select * from table where regexp_like('^[{][{]', text_field)
select * from table where regexp_like('^[[:punct:]]{2}', text_field)
None of which worked. For now, text_field like '{{' suffices, but I may want to include a more flexible version of this that would require regular expressions. What's wrong with my approach here? And what does this error message mean?
You are using the prestodb regex_like function in the wrong way:
regexp_like(string, pattern)
Evaluates the regular expression pattern and determines if it is
contained within string. This function is similar to the LIKE
operator, expect that the pattern only needs to be contained within
string, rather than needing to match all of string. In other words,
this performs a contains operation rather than a match operation. You
can match the entire string by anchoring the pattern using ^ and $:
SELECT regexp_like('1a 2b 14m', '\d+b'); -- true
I have 2 columns that I want to compare based on Postgres SIMILAR TO notation, in the example below it is the ~*. Lets call the columns: COLUMN1 and COLUMN2.
It works on most of the rows, then after further investigation if the value of either column has "++" the query failed.
SELECT
CASE
WHEN 'gcc' ~* 'gcc++' THEN 1
ELSE 2
END
with the following message
ERROR: invalid regular expression: quantifier operand invalid
Obviously the gcc++ string above need to be escaped.
Question:
Is the there a Postgres built-in function in postgres that escape the column values so that the comparison can be made safer? I'm thinking something like below ...
SELECT
CASE
WHEN escapeMe(COLUMN1) ~* escapeMe(COLUMN2) THEN 1
ELSE 2
END
FROM TABLE_T1
I am working with Sybase SQL and want to exclude all entries that look like this:
(NOT PRESENT)
So I tried using:
SELECT col FROM table WHERE col NOT LIKE '(%)'
Do you guys know what is happening? I think I need to escap ( somehow, but I do not know how. The following returns an error:
SELECT col FROM table WHERE col NOT LIKE '\(%\)' ESCAPE '\'
Kind Regards
Try this :
SELECT col FROM table WHERE col NOT LIKE ('(%)')
You might find this helpful
Sybase Event Stream Processor 5.0 CCL Programmers Guide - String Functions
like()
Scalar. Determines whether a given string matches a specified pattern string.
Syntax
like ( string, pattern )
Parameters
string A string.
pattern A pattern of characters, as a string. Can contain wildcards.
Usage
Determines whether a string matches a pattern string. The function returns 1 if the string matches the pattern, and 0 otherwise. The pattern argument can contain wildcards: '_' matches a single arbitrary character, and '%' matches 0 or more arbitrary characters. The function takes in two strings as its arguments, and returns an integer.
Note: In SQL, the infix notation can also be used: sourceString like patternString.
Example
like ('MSFT', 'M%T') returns 1.
I was studying some dynamic SQL(or perhaps it was regular SQL ?) today in Oracle, when I saw the pipe char being used in a line like this:
someVar := 'someValue' | 'someOtherValue'
This puzzled me. Is it BITWISE-OR like in TSQL ? Or is it something else? I am aware of the concatenation operator ( || ) , but it wasn't that one.
The documentation only shows it as a bitwise OR operator in TimesTen:
Bitwise OR of the two operands.
Sets a bit to 1 if one or both of the corresponding bits in Expression1 and Expression2 are 1. Sets a bit to 0 if both of the corresponding bits are 0.
But you didn't mention TimesTen, and it isn't valid in 'normal' SQL or PL/SQL.
The || operator is used for concatenating two strings, in Oracle a single | is not a valid operator. Are you sure that the posted code actually works, and that is indeed running on an Oracle database?
How can i query with to_tsquery for partial words match
For example
records
'hello old world'
'hello world'
'hi welcome'
'hi'
Here i wanted to return all records which includes words 'hello' or 'welcome'
SELECT * FROM accounts_order
WHERE name_tsvector ## to_tsquery('english','hello | welcome');
This returns properly.
Here i tried to implement using django 'objects.extra' query
queryset = Order.objects.extra(where=['name_tsvector ## to_tsquery(%s|%s)'], params=['hello','welcome'])
This query is nor working,got an exception
operator is not unique: unknown | unknown
LINE 1: ...nts_order" WHERE name_tsvector ## to_tsquery(E'olmin'|E'20')
^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts.
How can i pass this params part as a list?
It appears that you want the | within the string, ie a boolean OR in the tsquery:
regress=> select to_tsquery('english', 'olmin|20');
to_tsquery
----------------
'olmin' | '20'
(1 row)
Django is expanding %s to E'string', so you can't write %s|%s; as you've seen that expands to E'string1'|E'string2' which is interpreted as a boolean OR on the two strings. You must either:
Concatenate the two strings and | in Django with (eg) params=['hello'+'|'+'welcome'] and a single (%s) argument; or
Get Pg to concatenate the two strings with a literal |, eg (%s||'|'||%s)
I'd recommend the first option; it requires you to change the parameters you pass from Python but it produces vastly simpler SQL.
The original is invalid, it's trying to perform a boolean OR on two string literals:
regress=> select to_tsquery('english', 'olmin'|'20');
ERROR: operator is not unique: unknown | unknown
LINE 1: select to_tsquery('english', 'olmin'|'20');
^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts.