I want to select with neo4j the users, the amount of action movies they watched and how many of this action movies from each user where directed by Roland Emmerich.
I tried in various forms this query:
match (u:User)-[:watched]->(m:Movie)-[belongs_to]->
(Category{category_name:"Action"}) with count(m) as actionMovies, u
match (m:Movie)<-[directed]-(Director{director_name:"Roland Emmerich"})
return u, count(m) as MoviesFromRE, actionMovies
But the query execution never finishes. So I assume I'm doing something like a cross join.
Actually I expect to have the first count independent of the second since its already calculated when compiler comes to the second match clause.
Here is the relevant db view
Thanks for any suggestions and helps
Ok after get rid of the typos and including Movies in with clause:
match (u:User)-[:watched]->(m:Movie)-[:belongs_to]->
(:Category{category_name:"Action"}) with count(m) as actionMovies, u, m
match (m)<-[:directed]-(:Director{director_name:"Roland Emmerich"})
return u, count(m) as MoviesFromRE, actionMovies order by u.user_name
Now I get for actionMovies always 1. I think its because I group now in first with clause by Movies. I think I need a way to take the Movies from the first clause to the second but not group my first result by them.
The reason you are always getting 1 for actionMovies is in this clause:
WITH COUNT(m) AS actionMovies, u, m
That clause is saying (in part): "count the number of m nodes for every unique pair of u and m nodes". That count must always be 1.
This query should work better:
MATCH (u:User)-[:watched]->(am:Movie)-[:belongs_to]->(:Category{category_name:"Action"})
WITH u, COLLECT(am) AS ams
UNWIND ams AS m
OPTIONAL MATCH (m)<-[dir:directed]-(:Director{director_name:"Roland Emmerich"})
RETURN u, COUNT(dir) AS MoviesFromRE, SIZE(ams) AS actionMovies
ORDER BY u.user_name;
Related
The goal is to match the special and the normal and the condition is that they have a common city. The special's name should appear in Column E and the Normal's name should appear in Column F and they're being matched because they both are in the same city or have visited the same city.
So the data dump that, um, will be updated on a daily basis. So for example, Type Special - Caroline has visited in Cambridge. If there's also a Type Normal that has visited Cambridge. Hence both visited Cambridge and that's why they were matched.
All right. Another example is, um, let's see here, Regina. Is a special type. Now we want to match her with a type Normal. So in this case, there are no matches, so that would not appear in the outcomes.
Only those who have been tagged as a Special or a Normal can be matched. So the match always has to be between Special and Nornal and their names just have to appear here at the visited city.
Using FILTER Function thought it would work out, that will automatically detect a Special and a Normal when there is a common keyword in a city that they visited in, but it isn't working.
GoogleSheets
try:
=QUERY(A1:D17, "select max(A),B where D is not null group by B pivot D", 1)
update:
=ARRAYFORMULA(QUERY(SPLIT(FLATTEN(FILTER(A2:A17&"×"&B2:B17, D2:D17="special")&"×"&
TRANSPOSE(FILTER(A2:A17&"×"&B2:B17, D2:D17="normal"))), "×"),
"select Col1,Col3,Col4 where Col2=Col4", ))
I am implementing the example database Movies en Neo4j. I already search something about duplicated rows but I still have doubts
I am using XOR. I am getting the
MATCH (m:Movie)<-[r]-(p:Person)
WHERE m.title STARTS WITH 'The'
XOR (m.released = 1999 OR m.released = 2003)
RETURN m.title, m.released
So, my result is
As you can see, there are duplicated rows, I don't understand why there are doing that and the number of duplicated results is according to what?
I know that DISTINCT removes duplicated. But I am interested in understanding why the query duplicated the results and the number of duplicated is according to what?.
This is because you are matching
MATCH (m:Movie)<-[r]-(p:Person)
So the movie title will be returned for each person in the movie, so if there are 4 people in the movie, you will get four movie titles back. You can remove duplicates by matching only the movie
MATCH (m:Movie)
As Tomaz said, it is returning a row for every :Person that has a relationship to :Movie. If you concluded your query with just RETURN m and viewed the results, you probably would only see non-duplicated nodes appear. Otherwise, you can conclude the query with RETURN DISTINCT m to ensure that non-duplicated results are returned.
I need to match nodes only when every relationship the node has fullfills a whereclause:
MATCH (o:Otherthing)
WHERE id(o) = 1
MATCH (unknown:Thing)
WHERE (unknown)-[:DEPENDS_ON]->(:Thing)<-[:DEPENDS_ON*]-(:Thing)<-[:STARTED_WITH]-(o)
RETURN unknown
Every matched "Thing" should only have relationships labeled with "DEPENDS_ON" and all of them should fullfill the condition.
How can I achieve that?
This may work for you:
MATCH (u:Thing)-[:DEPENDS_ON]->(:Thing)<-[:DEPENDS_ON*]-(:Thing)<-[:STARTED_WITH]-(o)
WHERE ID(o) = 1
WITH u, COUNT(*) AS num
WHERE SIZE((u)--()) = num
RETURN u
The query uses an efficient degreeness check to get the total number of relationships for u, and compares that with the number of times u satisfied the MATCH. Also, since you are identifying o by its native ID (which I am assuming is always going to be the ID for an Otherthing), it is more efficient to not specify its label (to avoid a label verification operation).
Using MS Access and I have two tables, one is categories and the other is content.
My initial SQL statement, included below,takes a count of each content associated to a category and returns the count associated with each category.
So for each CATEGORY, I'm simply trying to return another count in which I count CONTENT that have a specific user level and are not deleted for each CATEGORY.
Below is what I am struggling with as I am not certain you can actually use COUNT like this.
COUNT(IIf([CONTENT.isDeleted]=0,1,0)) - COUNT(IIf([CONTENT.userLevel]=2)) AS userLevelCount
This is the full select statement with my addition but not working.
SELECT
CATEGORY.categoryId,
CATEGORY.categoryTitle,
CATEGORY.categoryDate,
CATEGORY.userLevel,
Last(CONTENT.contentDate) AS contentDate,
CATEGORY.isDeleted AS categoryDeleted,
COUNT(IIf([CONTENT.isDeleted]=0,1,0)) AS countTotal,
COUNT(IIf([CONTENT.isDeleted]=1,[CONTENT.contentID],Null)) AS countDeleted,
COUNT([CONTENT.categoryId]) - COUNT(IIf([CONTENT.isDeleted]=1,[CONTENT.contentID],Null))AS countDifference,
COUNT(IIf([CONTENT.isDeleted]=0,1,0)) - COUNT(IIf([CONTENT.userLevel]=2)) AS userLevelCount
FROM CATEGORY
LEFT JOIN CONTENT ON
CATEGORY.categoryId = CONTENT.categoryId
GROUP BY
CATEGORY.categoryId,
CATEGORY.categoryTitle,
CATEGORY.categoryDate,
CATEGORY.userLevel,
CATEGORY.isDeleted
HAVING (((CATEGORY.isDeleted)=0))
ORDER BY
CATEGORY.categoryTitle
you should be able to use the following
SUM(IIf([CONTENT.isDeleted]=0,1,0)) - COUNT(IIf([CONTENT.userLevel]=2,1,NULL)) AS userLevelCount
COUNT will not count NULL, but it will count zero. SUM will calculate the sum of all 1's - that's a second way of achieving the same.
IIF exists in the newer SQL versions
I believe I found the solution
Count(IIf([CONTENT.userLevel]=2,[CONTENT.contentID],Null)) AS countDifference2
This will return the count difference for CONTENT for each CATEGORY that isn't deleted and has a specific user level.
I'm trying to create a query for retrieving objects from a Doctrine database, sorted by the number of members of a specific one-to-many relationship.
More specifically: I have two Entities: Person and Federation. A person can be a member of one federation (Person has 'federation' relationship), and a federation may have n people (Federation as 'people' relationship).
I would like to create a DQL Query that would return the list of Federations, ordered by how many people are members of that Federation. Something along these lines:
SELECT f FROM AcmeStatsBundle:Federation f ORDER BY [number of members of f.people]
That would be the first step. There is an additional second step, which I don't know if is possible to achieve with a single query, which would be filtering the members of the relation prior the counting. Like so:
SELECT f FROM AcmeStatsBundle:Federation f ORDER BY [number of (f.people p where p.attr = value)]
That second one would be the optimal result, but the first one satisfies my needs, if the second case is not feasibly in a single query.
Thanks in advance.
You could do something along the lines of:
public function getFederationsOrderedByNumberOfPeople()
{
return $this->createQueryBuilder('f')
->addSelect('COUNT(p) AS HIDDEN personCount');
->leftJoin('f.people', 'p');
->groupBy('f')
->orderBy('personCount', 'DESC');
}
The HIDDEN keyword was added in Doctrine 2.2, it means that the selected field won't be in the results, and in this case that means you just get your entities back instead of an array.
Reference to DQL SELECT documentation: http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples
There are 5 aggregate functions in DQL you can use (Doctrine 2.2): AVG, COUNT, MIN, MAX and SUM.
The following query should work:
SELECT f
FROM AcmeStatsBundle:Federation f
LEFT JOIN f.people p
GROUP BY f.id
ORDER BY COUNT(p)
WHERE p.attr = :some_value
For more DQL trickery I suggest you look up official Doctrine docs.