Good Evening,
I am using Grails and I am trying to do an HQL Query
I have an object Opportunity and inside it an object Entity and inside the Entity a collection of Titles. Each Title object can be main or not (main is a boolean field that shows which of the titles is the default one). So the query that I am doing is this:
select opportunity from Opportunity as opportunity join opportunity.entity.titles as entityTitle with entityTitle.isMain is true
But this query fails with this message:
org.hibernate.hql.ast.InvalidWithClauseException: with-clause expressions did not reference from-clause element to which the with-clause was associated.
I have tried adding the Entity and Title tables and still it fails. If I remove the with clause it works correctly but I need to filter the titles.
Thanks.
Try this query:
select distinct op from Opportunity as op
inner join op.entity as ent
inner join ent.titles as tit
with tit.isMain is true
I found the problem. First I had to join the entity to the Opportunity and then join the titles to the Opportunity. So the query is like this:
select opportunity from Opportunity as opportunity
join opportunity.entity activeEntity
with activeEntity.isActive is true
join activeEntity.titles entityTitle
with entityTitle.isActive is true
Related
I don't get an except join to work in Cognos-11. Where or what am I missing?
Some understanding for a beginner in this branch would be nice ;-)
What I've tried so far is making two queries. The first one holds data items like "customer", "BeginningDate" and "Purpose". The second query holds data items like "customer", "Adress" and "Community".
What I'd like to accomplish is to get in query3: the "customers" from query1 that are not available in query2. To me it sounds like an except-join.
I went to the query work area, created a query3 and dragged an "except-join" icon on it. Then I dragged query1 into the upper space and query2 into the lower. What I'm used to getting with other joins, is a possibility to set a new link, cardinality and so on. Now double clicking the join isn't opening any pop-up. The properties of the except-join show "Set operation = Except", "Duplicates = remove", "Projection list = Manual".
How do I get query3 filled with the data item "customer" that only holds a list of customers which are solely appearing in query1?
In SQL terms, you want
select T2.C1
from T1
left outer join T2 on T1.C1 = T2.C1
where T2.C1 is null
So, in the query pane of a Cognos report...
Use a regular join.
Join using customer from both queries.
Change the cardinality to 1..1 on the query1 side and 0..1 on the query2 side.
In the filters for query3, add a filter for query2.customer is null.
EXCEPT is not a join. It is used to compare two data sets.
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-except-and-intersect-transact-sql?view=sql-server-2017
What you need is an INNER JOIN. That would be the join tool in the Toolbox in Cognos.
I has Model that has_many ModelItems. ModelItems belongs_to OtherModel which has a 'code' column.
I am looking to do something like this:
Model.find(1).model_items.includes(:other_model).order("other_model.code" :desc)
I am trying to sort based on the text of that related code column.
I have even tried:
ModelItems.where(model_id: 1).includes(:other_model).order("other_model.code" :desc)
I know I need an include or join here but no matter what I do I get a variation of this error:
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "other_model"
UPDATE
This is an example of not using the real model names bites you. I had it right all along.
The include was singular and the order model name needed to be plural - for clarity lets change other_model to widgit:
Model.find(1).model_items.includes(:widgit).order("widgits.code ASC")
includes in this context will execute 2 queries to create a pseudo outer join (also preload) and is conceptually as follows
SELECT * FROM model_items WHERE model_items.model_id = 1
SELECT * FROM other_models WHERE other_models.model_item_id IN ( [IDS FROM PREVIOUS QUERY])
You can enforce single query execution in a few ways:
eager_load - (ModelItems.eager_load(:other_model)) This is how includes works when you have the join table referenced in a hash finder query condition or when you add references.
references - (ModelItems.includes(:other_model).references(:other_model)) This enforces the eager_load path for include
where Hash finder method (ModelItems.includes(:other_model).where(other_models: {name: 'ABC'})) Here includes intelligently realizes that you have placed a condition on the relationship with other_model and will automatically create the join so that the query is not malformed. However this sort of query represents as an outer join but performs like an inner join which is less efficient *
However if you do not need the information in other_model and just want to use this as a sort mechanism then you can use joins (INNER JOIN) or left_joins (OUTER JOIN) which will allow you to sort this data but will not retrieve the attributes or instantiate any related objects under the other_model relationship
ModelItems.joins(:other_model)
# OR
ModelItems.left_joins(:other_model)
*These options can be combined as well as in the case of the includes where hash finder method I always recommend the following ModelItems.joins(:other_model).includes(:other_model).where(other_models: { name: 'ABC'}) (INNER JOIN). This will return the same data set as ModelItems.includes(:other_model).where(other_models: {name: 'ABC'}) (LEFT OUTER JOIN) however by utilizing an INNER JOIN it becomes more efficient than its LEFT OUTER JOIN version
Sidenote order("other_models.code" :desc) this is not valid. Instead you need to include the order direction in the String or make that String and Symbol e.g. (("other_models.code DESC") or ("other_models.code": :desc))
Add references
ModelItems
.where(model_id: 1)
.includes(:other_model)
.references(:other_model)
.order("other_model.code DESC")
According to Hive's documentation it supports NOT IN subqueries in a WHERE clause, provided that the subquery is an uncorrelated subquery (does not reference columns from the main query).
However, when I attempt to run the trivial query below, I get an error FAILED: SemanticException Cartesian products are disabled for safety reasons.
-- sample data
CREATE TEMPORARY TABLE foods (name STRING);
CREATE TEMPORARY TABLE vegetables (name STRING);
INSERT INTO foods VALUES ('steak'), ('eggs'), ('celery'), ('onion'), ('carrot');
INSERT INTO vegetables VALUES ('celery'), ('onion'), ('carrot');
-- the problematic query
SELECT *
FROM foods
WHERE foods.name NOT IN (SELECT vegetables.name FROM vegetables)
Note that if I use an IN clause instead of a NOT IN clause, it actually works fine, which is perplexing because the query evaluation structure should be the same in either case.
Is there a workaround for this, or another way to filter values from a query based on their presence in another table?
This is Hive 2.3.4 btw, running on an Amazon EMR cluster.
Not sure why you would get that error. One work around is to use not exists.
SELECT f.*
FROM foods f
WHERE NOT EXISTS (SELECT 1
FROM vegetables v
WHERE v.name = f.name)
or a left join
SELECT f.*
FROM foods f
LEFT JOIN vegetables v ON v.name = f.name
WHERE v.name is NULL
You got cartesian join because this is what Hive does in this case. vegetables table is very small (just one row) and it is being broadcasted to perform the cross (most probably map-join, check the plan) join. Hive does cross (map) join first and then applies filter. Explicit left join syntax with filter as #VamsiPrabhala said will force to perform left join, but in this case it works the same, because the table is very small and CROSS JOIN does not multiply rows.
Execute EXPLAIN on your query and you will see what is exactly happening.
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.
Article title is present in KnowledgeArticleVersion table and View Normalized Score is present in KnowledgeArticleViewStat table. The parent of both tables is KnowledgeArticle, but I can't join it to KnowledgeArticleVersion, because there is no relation name present in DB schema. Of cos, I can at first execute such query
Select k.ParentId, k.NormalizedScore From KnowledgeArticleViewStat k order by k.NormalizedScore
Then
SELECT Title, UrlName, KnowledgeArticleId FROM KnowledgeArticleVersion WHERE PublishStatus='Online' AND language ='en_US' and KnowledgeArticleId in (:ids)
But my religion forbids me from executing two queries instead of one.
Maybe someone can tell me the right way to perform join in SOQL.
Assuming the k.parentIds is what you use in :ids this would work:
SELECT id,Title , UrlName, KnowledgeArticleId, PublishStatus, language
FROM KnowledgeArticleVersion
WHERE PublishStatus='Online'
AND language ='en_US'
AND KnowledgeArticleId IN (SELECT ParentId
FROM KnowledgeArticleViewStat
)