Neo4j Chaining Queries - neo4j

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

Related

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.

Properly format an ActiveRecord query with a subquery in Postgres

I have a working SQL query for Postgres v10.
SELECT *
FROM
(
SELECT DISTINCT ON (title) products.title, products.*
FROM "products"
) subquery
WHERE subquery.active = TRUE AND subquery.product_type_id = 1
ORDER BY created_at DESC
With the goal of the query to do a distinct based on the title column, then filter and order them. (I used the subquery in the first place, as it seemed there was no way to combine DISTINCT ON with ORDER BY without a subquery.
I am trying to express said query in ActiveRecord.
I have been doing
Product.select("*")
.from(Product.select("DISTINCT ON (product.title) product.title, meals.*"))
.where("subquery.active IS true")
.where("subquery.meal_type_id = ?", 1)
.order("created_at DESC")
and, that works! But, it's fairly messy with the string where clauses in there. Is there a better way to express this query with ActiveRecord/Arel, or am I just running into the limits of what ActiveRecord can express?
I think the resulting ActiveRecord call can be improved.
But I would start improving with original SQL query first.
Subquery
SELECT DISTINCT ON (title) products.title, products.* FROM products
(I think that instead of meals there should be products?) has duplicate products.title, which is not necessary there. Worse, it misses ORDER BY clause. As PostgreSQL documentation says:
Note that the “first row” of each set is unpredictable unless ORDER BY is used to ensure that the desired row appears first
I would rewrite sub-query as:
SELECT DISTINCT ON (title) * FROM products ORDER BY title ASC
which gives us a call:
Product.select('DISTINCT ON (title) *').order(title: :asc)
In main query where calls use Rails-generated alias for the subquery. I would not rely on Rails internal convention on aliasing subqueries, as it may change anytime. If you do not take this into account you could merge these conditions in one where call with hash-style argument syntax.
The final result:
Product.select('*')
.from(Product.select('DISTINCT ON (title) *').order(title: :asc))
.where(subquery: { active: true, meal_type_id: 1 })
.order('created_at DESC')

How do I search for '%stars%' within a Postgresql array?

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%');

Is there a clean way to use ORDER BY inside an Arel NamedFunction Node?

I'm using ActiveRecord 4.2 / Arel 6.0 / Postgres and have the following inputs:
An Arel::Attributes::Attribute from an Arel::Table (column)
Several Arel::Nodes::Ordering nodes (orders)
I want to build an Arel::Nodes::NamedFunction with an aggregate function that includes the column specified by the Attribute and is ordered by the Ordering nodes.
The resulting SQL could look something like:
array_agg("posts"."id" ORDER BY "posts"."published_at" DESC)
My current solution is to first build an Arel::Nodes::SelectStatement, add the column and orders to it, convert it to SQL, strip the leading SELECT keyword, wrap it in an Arel::Nodes::SqlLiteral and pass that to the NamedFunction node:
select = Arel::Nodes::SelectStatement.new
select.cores.last.projections << column
select.orders = orders
sql = select.to_sql.sub(/^SELECT /, '')
literal = Arel::Nodes::SqlLiteral.new(sql)
array_agg = Arel::Nodes::NamedFunction.new('array_agg', [literal])
Obviously, this is a huge hack.
Keeping the ORDER BY outside the aggregate function is not an option, because it would conflict with the GROUP BY used to aggregate.
So is there a cleaner way to achieve this without abusing SelectStatement / SelectManager?
I don't know if this works for you but I found this to be a clean way to order in DESC order. You're using some different syntax then me but it seems like this is what you're looking for.
arel = Post.arel_table
query = arel.project(Arel.select('*'))
query.order(arel[:published_at].desc).to_sql
This is the best guess I have for what you're trying to do.
The solution is to use an Arel::Nodes::InfixOperation to build the "ORDER BY" node and an Arel::Nodes::StringJoin to build a comma separated list of Arel::Nodes::Ordering:
ordering = Arel::Nodes::StringJoin.new(orders)
order_by = Arel::Nodes::InfixOperation.new('ORDER BY', column, ordering)
array_agg = Arel::Nodes::NamedFunction.new('array_agg', [order_by])

Grails GORM to return random rows from table?

In my grails application I have:
keywords = Keyword
.findAll("from Keyword where locale = '$locale' order by rand() ", [max:20])
Assume there are thousands of rows in the table that match the above criteria. But it seems the rows that are returned from the table are not random but in the order the rows are stored in Db although within the context of 20 rows that are returned they are random. For my application to work I want this query to return completely random rows from the table like it could be row id 203 , row id 3789, row id 9087, row id 789, and so on. How is that possible?
I use the following style:
Keyword.executeQuery('from Keyword order by rand()', [max: 9])
and it returns random rows from the entire table (we're using MySQL).
I'm not sure why execute query would behave differently from findAll though.
If you want to use a .withCriteria you can do that workaround:
User.withCriteria {
eq 'name', 'joseph'
sqlRestriction " order by rand()"
}
It's important to say that sometimes ( depends on the Criteria query created ) it's necessary to add a 1=1 in sqlRestriction because it adds an "and" condition in generated query.
So if you have a sqle exception use:
sqlRestriction " 1=1 order by rand()"

Resources