SQL overlap statement - sql

I'm trying to do overlap in SQL (using postgres) but receive an syntax error. And i do not know why I'm getting error and whats wrong with my SQL Statement
Error text
[42601] ERROR: syntax error at or near "[" Position: 296
SQL Statement
SELECT *,
ARRAY_AGG("reserve"."state_id" ) AS "states" FROM "orders_order"
JOIN "reserve" ON ("order"."id" = "reserve"."order_id")
GROUP BY "order"."id"
HAVING (NOT (ARRAY_AGG("reserve"."state_id" )&& ['test']::varchar(255)[]))

As documented in the manual there are two ways to specify an array:
First with the array keyword:
array['test']
or as a string enclosed with curly braces:
'{test}'::text[]
In the second case the casting might or might not be needed depending on the context on where it's used.
There is no need to cast it to a varchar(255)[] array. text[] will do just fine - especially when comparing it to the result of an array_agg() which returns text[] as well.

Related

Operator does not exist date=integer when filtering for dates in postgreSQL

I have a large data set on dbeaver (postgreSQL), and I am trying to filter for the following:
select * from raw_data_file where data_file_group_id = 2592 and dl_date = 2022-06-15
However, I am getting an error for the dl_date part of the filter- any suggestions?
SQL Error [42883]: ERROR: operator does not exist: date = integer¶ Hint: No operator matches the given name and argument types. You might need to add explicit type casts.¶ Position: 74
Stu's comment is correct. Use quotes, single quotes, otherwise the subexpression looks like a couple of subtractions.

Using try_cast in snowflake to deal with very long numbers

I'm using try_cast in snowflake to convert any long values in sql to NULL.
Here is my code:
When I try running the above code, I'm getting the error as below:
I'm flattening a JSON array and using try_cast to make any large values to NULL because I was getting an error Failed to cast variant value {numberLong: -8301085358432}
SELECT try_cast(item.value:price) as item_price,
try_cast(item.value:total_price_bill) as items_total_price
FROM table, LATERAL FLATTEN(input => products) item
Error:
SQL compilation error error at line 1 at position ')'.
I don't understand where I'm doing wrong
you are using wrong syntax for try_cast. according to snowflake documentations the syntax is :
TRY_CAST( <source_string_expr> AS <target_data_type> )
and also note:
Only works for string expressions.
target_data_type must be one of the following:
VARCHAR (or any of its synonyms)
NUMBER (or any of its synonyms)
DOUBLE
BOOLEAN
DATE
TIME
TIMESTAMP, TIMESTAMP_LTZ, TIMESTAMP_NTZ, or TIMESTAMP_TZ
so for example you have to have something like this if item.value:price is string:
select try_cast(item.value:price as NUMBER) as item_price,
....

How to use ANY instead of IN in a WHERE clause?

I used to have a query like in Rails:
MyModel.where(id: ids)
Which generates sql query like:
SELECT "my_models".* FROM "my_models"
WHERE "my_models"."id" IN (1, 28, 7, 8, 12)
Now I want to change this to use ANY instead of IN. I created this:
MyModel.where("id = ANY(VALUES(#{ids.join '),('}))"
Now when I use empty array ids = [] I get the folowing error:
MyModel Load (53.0ms) SELECT "my_models".* FROM "my_models" WHERE (id = ANY(VALUES()))
ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Position: 75: SELECT "social_messages".* FROM "social_messages" WHERE (id = ANY(VALUES()))
from arjdbc/jdbc/RubyJdbcConnection.java:838:in `execute_query'
There are two variants of IN expressions:
expression IN (subquery)
expression IN (value [, ...])
Similarly, two variants with the ANY construct:
expression operator ANY (subquery)
expression operator ANY (array expression)
A subquery works for either technique, but for the second form of each, IN expects a list of values (as defined in standard SQL) while = ANY expects an array.
Which to use?
ANY is a later, more versatile addition, it can be combined with any binary operator returning a boolean value. IN burns down to a special case of ANY. In fact, its second form is rewritten internally:
IN is rewritten with = ANY
NOT IN is rewritten with <> ALL
Check the EXPLAIN output for any query to see for yourself. This proves two things:
IN can never be faster than = ANY.
= ANY is not going to be substantially faster.
The choice should be decided by what's easier to provide: a list of values or an array (possibly as array literal - a single value).
If the IDs you are going to pass come from within the DB anyway, it is much more efficient to select them directly (subquery) or integrate the source table into the query with a JOIN (like #mu commented).
To pass a long list of values from your client and get the best performance, use an array, unnest() and join, or provide it as table expression using VALUES (like #PinnyM commented). But note that a JOIN preserves possible duplicates in the provided array / set while IN or = ANY do not. More:
Optimizing a Postgres query with a large IN
In the presence of NULL values, NOT IN is often the wrong choice and NOT EXISTS would be right (and faster, too):
Select rows which are not present in other table
Syntax for = ANY
For the array expression Postgres accepts:
an array constructor (array is constructed from a list of values on the Postgres side) of the form: ARRAY[1,2,3]
or an array literal of the form '{1,2,3}'.
To avoid invalid type casts, you can cast explicitly:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Related:
PostgreSQL: Issue with passing array to procedure
How to pass custom type array to Postgres function
Or you could create a Postgres function taking a VARIADIC parameter, which takes individual arguments and forms an array from them:
Passing multiple values in single parameter
How to pass the array from Ruby?
Assuming id to be integer:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
But I am just dabbling in Ruby. #mu provides detailed instructions in this related answer:
Sending array of values to a sql query in ruby?

PostgreSQL Concat 2 numbers gives me error

I'm trying to concat 2 numbers from two different columns, those are chain_code and shop_code.
I tried this:
SELECT CONCAT(`shop_code`, `shop_code`) AS myid FROM {table}
But I get an error:
ERROR: operator does not exist: ` integer
LINE 1: SELECT CONCAT(`shop_code`, `shop_code`) AS myid FROM...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
I even tried to convert it to string but couldn't ... CONCAT(to_char(chain_code, '999')...) ... but it says there is no such a function called 'to_sting' (found on PostgreSQL Documentation)
First: do not use those dreaded backticks ` , that's invalid (standard) SQL.
To quote an identifier use double quotes: "shop_code", not `shop_code`
But as those identifiers don't need any quoting, just leave them out completely. In general you should avoid using quoted identifiers. They cause much more trouble than they are worth it.
For details on specifying SQL identifiers see the manual: http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
But concat() only works on text/varchar values, so you first need to convert/cast the integer values to varchar:
SELECT CONCAT(chain_code::text, shop_code::text) AS myid FROM...
but it says there is no such a function called 'to_sting'
Well, the function is to_char(), not to_sting().
Using to_char() is an alternative to the cast operator ::text but is a bit more complicated in this case:
SELECT CONCAT(to_char(chain_code,'999999'), to_char(shop_code, '999999')) AS myid FROM...
The problem with to_string() in this context is, that you need to specify a format mask that can deal with all possible values in that column. Using the cast operator is easier and just as good.
Update (thanks mu)
As mu is to short pointed out, concat doesn't actually need any cast or conversion:
SELECT CONCAT(chain_code, shop_code) AS myid FROM...
will work just fine.
Here is an SQLFiddle showing all possible solutions: http://sqlfiddle.com/#!15/2ab82/3

PostGIS query failing due to escape string?

I have this Postgres/PostGIS query:
UPDATE raw.geocoding
SET the_geom = ST_Transform(ST_GeomFromText('POINT(((E'-96.6864379495382')::float8) ((E'32.792527154088')::float8))', 4326),3081)
WHERE id=((10793455)::int4)
When I run it, I get this error:
ERROR: syntax error at or near "')::float8) ((E'"
LINE 2: ...sform(ST_GeomFromText('POINT(((E'-96.6864379495382')::float8...
^
********** Error **********
ERROR: syntax error at or near "')::float8) ((E'"
SQL state: 42601
Character: 94
I'm scratching my head because PostGIS doesn't have a problem with escaped data (for example), and the query was generated from npgsql based on this parameterized query:
UPDATE raw.geocoding
SET the_geom = ST_Transform(ST_GeomFromText('POINT(:longitude :latitude)', 4326),3081)
WHERE id=:id
I am running Postgres 9.1.5 and PostGIS 2.0.1.
The error results from unescaped single quotes in the string. The standard way is to double them:
UPDATE raw.geocoding
SET the_geom = ST_Transform(ST_GeomFromText(
'POINT(((E''-96.6864379495382'')::float8)
((E''32.792527154088'')::float8))', 4326),3081)
WHERE id=((10793455)::int4)
This fixes the string literal, but you have more errors.
Like #Paul hinted in a comment, ST_GeomFromText() expects the geometry WKT POINT(0 0). The explicit cast to float8 makes it look like you are trying to enter the Postgres function point() (had me confused at first). Simplify to:
UPDATE raw.geocoding
SET the_geom = ST_Transform(ST_GeomFromText(
$$POINT(96.6864379495382 32.792527154088)$$, 4326), 3081)
WHERE id = 10793455
Note also, how I use dollar quoting in the second example to avoid having to escape single quotes altogether. As there aren't any single quotes left in your string literal after fixing the syntax, you might as well use single quotes again. Your parametrized query:
UPDATE raw.geocoding
SET the_geom = ST_Transform(ST_GeomFromText(
$$POINT(:longitude :latitude)$$::geometry, 4326), 3081)
WHERE id = :id
You can add a cast to geometry to make it clear, like #Paul advises in his comment. But it works without explicit cast, too.