How do I search for '%stars%' within a Postgresql array? - ruby-on-rails

I am trying to find a record in a Postgresql Query, where I have a column 'alternate_names'
t.text "alternate_names", default: [], array: true
And, I would like to find the following record:
altenate_names = ['All Stars']
where my criteria is 'Stars'
In other words, how can I write the following
select * from group where '%Stars%' = ANY(alternate_names);
But this won't return my record above because it has the array ['All Stars']...so, how can I perform an ILIKE '%stars%' with an array?

if you want LIKE operator:
select * from group where alternate_names::text like '%Stars%';
Comparing text representation of array against pattern is not effective, but wildcard before pattern won't be effective in any query on text[]

You can use unnest to check for partial match of all elements in an array.
Ex:
select * from group where exists (select 1 from unnest(alternate_names) as a_names where a_names like '%Stars%');

Related

Neo4j Chaining Queries

Is there a CypherQL equivalent of the below SQL statement?
SELECT name from table t
WHERE t.field IN
(SELECT * from othertable ot)
Was thinking it may be something like this?
MATCH (e)--(m)
MATCH (a) where a.field in e.otherfield return a
(e) returns a list of strings and i want to only execute the second query based on those strings.
I'm not sure if you meet your expectations, and I wouldn't recommend it honestly, do you mean below?
MATCH(othertable)
WITH REDUCE(values = [], key IN KEYS(othertable) | values + othertable[key]) AS values
MATCH(t) WHERE t.field IN values
RETURN t.name

How to select specific column types in SQLite3?

PRAGMA table_info(myTable)
This query selects all the info in a table, for example: if there are 2 columns in a table then this query will select all the column names, column types e.t.c
I just want add one clause i.e I want to get info of specific columns that I define in the query.
Like this:
PRAGMA table_info(myTable) where columnNames = 'a' and columnNames = 'b' // this is wrong query but I just mentioned it to make my question more clear.
How can I do this?
You can pragma_table_info() in a query with a WHERE clause:
SELECT *
FROM pragma_table_info('myTable') -- note the single quotes
WHERE name IN ('a', 'b') -- equivalent: name = 'a' OR name = 'b'
See the demo.

JSONB Querying array

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")

How to properly parameterize my postgresql query

I'm trying to parameterize my postgresql query in order to prevent SQL injection in my ruby on rails application. The SQL query will sum a different value in my table depending on the input.
Here is a simplified version of my function:
def self.calculate_value(value)
calculated_value = ""
if value == "quantity"
calculated_value = "COALESCE(sum(amount), 0)"
elsif value == "retail"
calculated_value = "COALESCE(sum(amount * price), 0)"
elsif value == "wholesale"
calculated_value = "COALESCE(sum(amount * cost), 0)"
end
query = <<-SQL
select CAST(? AS DOUBLE PRECISION) as ? from table1
SQL
return Table1.find_by_sql([query, calculated_value, value])
end
If I call calculate_value("retail"), it will execute the query like this:
select location, CAST('COALESCE(sum(amount * price), 0)' AS DOUBLE PRECISION) as 'retail' from table1 group by location
This results in an error. I want it to execute without the quotes like this:
select location, CAST(COALESCE(sum(amount * price), 0) AS DOUBLE PRECISION) as retail from table1 group by location
I understand that the addition of quotations is what prevents the sql injection but how would I prevent it in this case? What is the best way to handle this scenario?
EDIT: I added an extra column to be fetched from the table to highlight that I can't use pick to get one value.
find_by_sql is used when you want to populate objects with a single line of literal SQL. But we can use ActiveRecord for most of this, we just need one single column. To make objects, use select. If you just want results use pluck.
As you're picking from a fixed set of strings there's no risk of SQL injection in this code. Use Arel.sql to pass along a SQL literal you know is safe.
def self.calculate_value(result_name)
sum_sql = case result_name
when "quantity"
"sum(amount)"
when "retail"
"sum(amount * price)"
when "wholesale"
"sum(amount * cost)"
end
sum_sql = Arel.sql(
"coalesce(cast(#{sum_sql} as double precision), 0) as #{result_name}"
)
return Table1
.group(:location)
# replace pluck with select to get Table1 objects
.pluck(:location, sum_sql)
end

Retrieve database records in Rails

My model named Person contains 3 columns namely name,age,gender.
Now how to get all the rows if the gender = "male". I try to
fetch the data as shown below.
p = Person.find_by_gender("male")
The above statement properly worked. But it returns only 1 record. Because, the statement is converted to like following query.
SELECT "persons".* FROM "persons" WHERE "persons"."gender" = $1 LIMIT 1 [["gender", "male"]]
Due to limit is set to 1 it returns only 1 record. So, how to unset the limit? My requirement to get all the records in table if gender
matches "male".
use where
Person.where(gender: "male")
find method always returns only one record
In rails find methods always return single record that's why it returning single record.
Person.find_by_gender("male")
Use Where which give you array of matching records(which is ActiveRecord::Relation)
Person.where(:gender => "male")

Resources