In a postgres database I have a string field code in orders table. The field contains values like 'COA-38-A', 'EFILLDIRT' and 'HE60LS-A'. There is a form on UI to filter orders based on code and only integer values are allowed in the field.
The query should filter the orders by integer values in the code field i.e if 30 is entered, the query should return orders with code 'COA-38-A' and 'HE60LS-A' because the query contains >=
I tried adding ::integer in the query:
Order.where('code::integer >= ?', params[:code])
but got the following error:
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer
Is there any way to filter by only integer values?
try this?
Order.where("regexp_replace(0||code, '[^0-9]+', '', 'g')::integer >= ?", params[:code].to_i)
Related
I have the following a column in a PostgreSQL table that has a JSONB field with data like:
[{"id":33,"url":"","name":"test"}, {"id":45,"url":"","name":"test"}]
I'm trying to query it and return the element that matches the id. I have the following query in Rails, but it doesn't seem to be matching:
Book.where('data #> ?', '[{"id": 33}]')
Since you only need some elements in the jsonb array, you will need to transform those into records and cross join them with their parents:
Book.joins(", jsonb_array_elements(books.data) obj")
.where("obj->>'id' = '33'")
.select("obj")
I am using Rails 5, PostgreSQL. I need to get count of users grouped by created_at day, using postgres DATE_TRUNC.
The conditions are users created within a date range and have orders within the same date range.
Below is my code which result in an AmbiguousFunction error
Spree::User.joins(:orders)
.where(spree_orders: { completed_at: params[:start_date]..params[:end_date] })
.order("DATE_TRUNC('day', 'created_at')")
.group("DATE_TRUNC('day', 'created_at')")
.count
The params of start_date and end_date are as follow:
params[:end_date] = Time.current.end_of_day
params[:start_date] = (Time.current - 200.days).beginning_of_day
I get the following error
ActiveRecord::StatementInvalid: PG::AmbiguousFunction: ERROR: function date_trunc(unknown, unknown) is not unique
and even when I explicitly write spree_users.created_at I get the same error.
Is there a better way to achieve the required or a solution for this error?
ActiveRecord::StatementInvalid: PG::AmbiguousFunction
This error occurs when our query contains a column name, which may belong to more than one table. For example, we have two tables, User and Company, and both of them have a column called name. Now the following query would raise an error similar to the one that you are facing:
User.joins(:companies).where("name = ABC")
This happens because we do not specify which table to search the name in. Hence, ActiveRecord gets confused and cannot create a unique query.
In the case mentioned above, the error can be resolved simply by prepending spree_users to the created_at column name used in the order and group queries:
Spree::User.joins(:orders)
.where(spree_orders: { completed_at: params[:start_date]..params[:end_date] })
.order("DATE_TRUNC('day', 'spree_users.created_at')")
.group("DATE_TRUNC('day', 'spree_users.created_at')")
.count
I think you can use date function from sql to get date of timestamp field, and since table User and SpreeOrder has created_at field, you should inform table name (spree_orders.created_at)
Spree::User.joins(:orders)
.where(spree_orders: { completed_at: params[:start_date]..params[:end_date]})
.order("date(spree_orders.created_at)")
.group("date(spree_orders.created_at)")
.count
I want to query an hStore column on PG database and return ONLY the values corresponding to a specific key and value.
hstore column contains the information in the below manner
hours: {"tue_1_open"=>"19:30", "tue_1_close"=>"21:45"}
I am able to query based on key and value as follows
Model.where("hours #> hstore(:key,:value )", key: "tue_1_open", value: "19:30")
But I want to query whose value is grater than specific time. I want query something like
Model.where("hours #> hstore(:key,:value )", key: "tue_1_open", value: ">= 19:30")
Any idea how we can achieve this?
You can try to get greater value in integer not time
Model.where("(hours ? 'tue_1_open')::int > 19")
for datetime hours value of 'tue_1_open' should be a Datetime value
Model.where("(hours ? 'tue_1_open')::timestamp > Time.now")
I have a view which is exporting some columns, one column is called
'created_at' type:"timestamp without timezone" format: "2014-03-20 12:46:36.590253"
In rails I have a method, which is getting data from the view and is trying to filter the data by a date. I tried rapping created_at into date() but is still not working.
Any ideas?
return ActiveRecord::Base.connection.select_all("
select * from db_functions where date(created_at) >= #{date_p} AND date(created_at) <= #{date_p}")
PG::UndefinedFunction: ERROR: operator does not exist: date >= integer
LINE 2: ...select * from db_functions where date(created_at) >= 2014-03...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
The first noticeable problem is that your time is not quoted. This is causing the time to be treated as integer. To fix this, you could simply wrap date_p with quotes or use ActiveReocrd::ConnectionAdapters#quote as:
conn = ActiveRecord::Base.connection
return conn.select_all("select * from db_functions
where date(created_at) >= #{conn.quote(date_p)}
AND date(created_at) <= #{conn.quote(date_p)}")
Another option, instead of converting each created_at to date in where clause, you could modify date_p to be beginning of the day value and remove the "date" conversion altogether. Also, instead of using values directly in the query, it's better to use prepared statements (Linked article is a couple of years old, but explains prepared statements clearly with examples).
Then there is also the task of modifying the date time parameter to beginning of day. Given that date_p is a string and not a time, here is what you can do:
date_p = Time.zone.parse("2014-03-20 12:46:36.590253").beginning_of_day.utc
return ActiveRecord::Base.connection.select_all("select * from db_functions
where created_at >= ?
AND created_at <= ?", date_p, date_p)
I have a column with the type of Varchar in my Postgres database which I meant to be integers... and now I want to change them, unfortunately this doesn't seem to work using my rails migration.
change_column :table1, :columnB, :integer
Which seems to output this SQL:
ALTER TABLE table1 ALTER COLUMN columnB TYPE integer
So I tried doing this:
execute 'ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)'
but cast doesn't work in this instance because some of the column are null...
any ideas?
Error:
PGError: ERROR: invalid input syntax for integer: ""
: ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)
Postgres v8.3
It sounds like the problem is that you have empty strings in your table. You'll need to handle those, probably with a case statement, such as:
execute %{ALTER TABLE "table1" ALTER COLUMN columnB TYPE integer USING CAST(CASE columnB WHEN '' THEN NULL ELSE columnB END AS INTEGER)}
Update: completely rewritten based on updated question.
NULLs shouldnt be a problem here.
Tell us your postgresql version and your error message.
Besides, why are you quoting identifiers ? Be aware that unquoted identifiers are converted to lowercase (default behaviour), so there might be a problem with your "columnB" in your query - it appears quoted first, unquoted in the cast.
Update: Before converting a column to integer, you must be sure that all you values are convertible. In this case, it means that columnB should contains only digits (or null).
You can check this by something like
select columnB from table where not columnB ~ E'^[0-9]+$';
If you want your empty strings to be converted to NULL integers, then run first
UPDATE table set columnB = NULL WHERE columnB = '';