I'm using:
typeorm = 0.2.7
pg = 7.4.3
PostgreSQL = 9.6
For Repository.find() it seems there is some support for automatically turning null values in where conditions into "IS NULL" clauses in the generated SQL. Is this also done for inner join conditions?
Asked a different way, should the following work?
userRepo.createQueryBuilder('user')
.innerJoin(
'user.phone',
'phone',
'phone.type = :type',
{ type: null }
)
.getMany();
From the debugging I've done so far, it seems to generate "phone.type = $X", and the query doesn't retrieve the expected results.
Related
I have setup a PostgreSQL array field identical to this example on edgeguides. I am querying on these fields like:
Book.where("'fantasy' = ANY (tags)")
But what I need is to query the inverse of this; all records where tags does not include 'fantasy' (in this example).
Anyone have any guidance? I cannot find much documentation on working with a PostgreSQL array field outside of the aforementioned guide.
You can negate your condition
Book.where("NOT('fantasy' = ANY (tags))")
So you can modify query to get records with NULL records also:
Book.where("NOT('fantasy' = ANY (tags)) or tags IS NULL")
Also you can run these queries in psql and check results
SELECT * FROM book WHERE NOT('fantasy' = ANY (tags));
SELECT * FROM book WHERE NOT('fantasy' = ANY (tags)) OR tags IS NULL;
SELECT * FROM book WHERE 'fantasy' = ANY (tags)
Maybe there is no records without tag 'fantasy'?
Try this:
Book.where.not('tags #> ARRAY[?]', "fantasy")
im using grails 2.4.5
i want to retrieve the top 3 customers based on how many contracts they have
im trying to execute this code
def customers = Customer.executeQuery("Select cu, (Select count(*) from Contract co where co = cu.contract) from Customer cu",
[max: 3])
and it returns this error
left and right hand sides of a binary logic operator were incompatibile [com.cms.Contract : java.util.Set(com.cms.Customer.contract)]
i understand that the co and cu.contract types are not the same but i dont get why. can someone help me how this executeQuery of grails work. this is the only framework i used that have a static query execution but still need to follow a certain format.
what i really want to do is to generate a query like this
Select * from Customer cu order by (Select count(*) from Contract co where co.id = cu.id)
You could try a Criteria query with projections:
def results = Customer.createCriteria().list() {
createAlias( 'contracts', 'contractalias' )
projections {
groupProperty( 'contractalias.contract' )
count( 'contractalias.contract', 'contractCount' )
}
maxResults( 3 )
order 'contractCount', 'desc'
}
I'm not 100% of your field names so had to assume in above query.
It's often useful to turn on sql logging when trying out these queries e.g. add following to development DataSource
development {
dataSource {
...
logSql = true
}
}
I have an issue: When I am trying to join two tables which do not have a foreign key or a direct entity relation through my java code within themselves. I am using the below JPQL query: -
SELECT p FROM P p, OM orgm WHERE p.o.id = orgm.o.id and p.u.id = orgm.u.id and orgm.ma = true and p.u.id = ? AND p.o.id IN (:oId);
But this turns to a MySQL query which has a "cross join" which obviously is expensive.
What I need is to make sure that a similar query gives me an inner join MySQL query between the two tables.
I am trying to make usage of the "WITH" clause but seems that it doesn't work with inner join.
Please revert what can be done in this scenario.
Thanks in advance.
Im trying to query my db for records that are similar to the currently viewed record (based on taggings), which I have working but I would like to randomize the order.
my development environment is mysql so I would do something like:
#tattoos = Tattoo.tagged_with(tags, :any => true).order("RAND()").limit(6)
which works, but my production environment is heroku which is using postgresql so I tried using this:
#tattoos = Tattoo.tagged_with(tags, :any => true).order("RANDOM()").limit(6)
but I get the following error:
ActionView::Template::Error (PGError: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
SELECT DISTINCT tattoos.* FROM "tattoos" JOIN taggings
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477 ON
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.taggable_id = tattoos.id AND
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.taggable_type = 'Tattoo' WHERE
(tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.tag_id = 3 OR
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.tag_id = 4 OR
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.tag_id = 5 OR
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.tag_id = 24 OR
tattoos_taggings_color_fantasy_newschool_nerdy_tv_477.tag_id = 205) ORDER BY RANDOM() LIMIT 6):
After analyzing the query more closely, I have to correct my first draft. The query would require a DISTINCT or GROUP BY the way it is.
The (possibly) duplicate tattoos.* come from first joining to (possibly) multiple rows in the table taggings. Your query engine then tries to get rid of such duplicates again by using DISTINCT - in a syntactically illegal way.
DISTINCT basically sorts the resulting rows by the resulting columns from left to right and picks the first for each set of duplicates. That's why the leftmost ORDER BY column have to match the SELECT list.
MySQL is more permissive and allows the non-standard use of DISTINCT, but PostgreSQL throws an error.
ORMs often produce ineffective SQL statements (they are just crutches after all). However, if you use appropriate PostgreSQL libraries, such an illegal statement shouldn't be produced to begin with. I am no Ruby expert, but something's fishy here.
The query is also very ugly and inefficient.
There are several ways to fix it. For instance:
SELECT *
FROM (<query without ORDER BY and LIMIT>) x
ORDER BY RANDOM()
LIMIT 6
Or, better yet, rewrite the query with this faster, cleaner alternative doing the same:
SELECT ta.*
FROM tattoos ta
WHERE EXISTS (
SELECT 1
FROM taggings t
WHERE t.taggable_id = ta .id
AND t.taggable_type = 'Tattoo'
AND t.tag_id IN (3, 4, 5, 24, 205)
)
ORDER BY RANDOM()
LIMIT 6;
You'll have to implement it in Ruby yourself.
not sure about the random, as it should work.
But take a note of http://railsforum.com/viewtopic.php?id=36581
which has code that might suit you
/lib/agnostic_random.rb
module AgnosticRandom
def random
case DB_ADAPTER
when "mysql" then "RAND()"
when "postgresql" then "RANDOM()"
end
end
end
/initializers/extend_ar.rb (name doesn't matter)
ActiveRecord::Base.extend AgnosticRandom
I'm attempting a transition from MySQL to what seems to be the stricter and less Rails-friendly PostgreSQL.
I'm running into this funny conundrum:
irb(main):015:0> puts w.to_sql
SELECT DISTINCT ON (vendors.id) vendors.*
FROM "vendors"
INNER JOIN "locations" ON "locations"."locatable_id" = "vendors"."id"
AND "locations"."locatable_type" = 'Vendor'
WHERE (locations.latitude IS NOT NULL AND locations.longitude IS NOT NULL)
But...
irb(main):017:0> puts w.order('vendors.id').to_sql
SELECT * FROM (
SELECT DISTINCT ON (vendors.id) vendors.*
FROM "vendors"
INNER JOIN "locations" ON "locations"."locatable_id" = "vendors"."id"
AND "locations"."locatable_type" = 'Vendor'
WHERE (locations.latitude IS NOT NULL AND locations.longitude IS NOT NULL)
) AS id_list ORDER BY id_list.alias_0
This, despite the fact that just adding ORDER BY vendors.id works just fine as a valid PostgreSQL query. Instead of just adding that, it does something super funny and produces an invalid query at the end of the day:
ActiveRecord::StatementInvalid: PGError: ERROR: column id_list.alias_0 does not exist
LINE 1: ...tions.longitude IS NOT NULL)) AS id_list ORDER BY id_list.al...
Any clue what I should look at?
I've run into the same problem. Looks like it was a bug in Arel causing DISTINCT ON not to play nice with ORDER when using PostgreSQL.
The original bug is no longer visible since Rails has moved from Lighthouse to github issues but you can take a look at the Google cache. There's a comment on a more recent pull request which indicates the issue was fixed after Rails 3.0.7 was released. Looks like it will be in 3.1 but I couldn't verify as some of the gems I'm using are not yet compatible.
The current work-around is to use find_by_sql.