Mysql Join and count for each categories - join

Hi I have a tables like this
exams
id | exam_name
1 | computer science
2 | Environment science
exam_students
id | exam_id | student_name
1 | 1 | Josh
2 | 1 | Michael
3 | 1 | John
I just need to join and count the total students of each exam and output something like this
exam_name | total_students |
computer science | 3 |
Environment science| 0 |
Thank you for your any help and suggestions

Try this
SELECT
a.exam_name, count(b.id) AS total_students
FROM
exams a
LEFT JOIN exam_students b ON a.id = b.exam_id
GROUP BY
a.id
Hope this help

Related

Neo4j - Create relationship within label on property

I'm importing a dataset of the following structure into Neo4j:
| teacher | student | period |
|:---------------:|---------|:------:|
| Mr. Smith | Michael | 1 |
| Mrs. Oliver | Michael | 2 |
| Mrs. Roth | Michael | 3 |
| Mrs. Oliver | Michael | 4 |
| Mrs. Oliver | Susan | 1 |
| Mrs. Roth | Susan | 2 |
My goal is to create a graph where a teacher "sends" students from one period to the next, showing the flow of students between teachers. The above graph for instance, would look like this:
Using words, my logic looks like this:
Generate a unique node for every teacher
For each student, create a relationship connecting the earliest period to the next earliest period, until the latest period is reached.
My code so far completes the first step:
LOAD CSV WITH HEADERS FROM 'file:///neo_sample.csv' AS row // loads local file
MERGE(a:teacher {teacher: row.teacher}) // used merge instead of create to produce unique teacher nodes.
Here is how you can produce your illustrated graph.
Assuming your CSV file looks like this:
teacher;student;period
Mr. Smith;Michael;1
Mrs. Oliver;Michael;2
Mrs. Roth;Michael;3
Mrs. Oliver;Michael;4
Mrs. Oliver;Susan;1
Mrs. Roth;Susan;2
then this query should work:
LOAD CSV WITH HEADERS FROM 'file:///neo_sample.csv' AS row FIELDTERMINATOR ';'
WITH row.teacher AS t, row.student AS s, row.period AS p
ORDER BY p
WITH s, COLLECT({t:t, p:p}) AS data
FOREACH(i IN RANGE(0, SIZE(data)-2) |
MERGE(a:Teacher {name: data[i].t})
MERGE(b:Teacher {name: data[i+1].t})
MERGE (a)-[:SENDS {student: s, period: data[i].p}]->(b)
)

How to use COUNT to calculate number of occurence in two columns?

I am having two tables.
Table 1: Consists of name of the players and their id's.
tournament=> select * from Players;
id | name
----+--------
1 | Rahul
2 | Rohit
3 | Ramesh
4 | Roshan
5 | Ryan
6 | Romelu
7 | Roman
8 | Rampu
(8 rows)
Table 2:Consist of both the opponents playing each other, column1 contains the name of the winner and column2 loser. So this means that both taking part in that Match.
tournament=> select * from Matches;
id | winner | loser
----+--------+-------
1 | 1 | 2
2 | 3 | 4
3 | 5 | 6
4 | 7 | 8
(4 rows)
Now I want to count number of matches played by different players, I have counted the number of matches won by players by following query.
SELECT Players.id, COUNT(Matches.winner) AS Points FROM Players LEFT JOIN (SELECT * from Matches) AS Matches ON Players.id = Matches.winner GROUP by Players.id Order by Points desc, Players.id;
id | points
----+---
1 | 1
3 | 1
5 | 1
7 | 1
2 | 0
4 | 0
6 | 0
8 | 0
(8 rows)
But I am not able to get the logic of how should I calculate the number of matches played by each player?
From above Matches table we can see that each players has played once but I am not able to write that in psql.
A simple nested subquery is needed, as follows:
SELECT pl.id,
(
SELECT COUNT(id)
FROM Matches
WHERE winner = pl.id OR loser = pl.id
) AS matches
FROM Players pl
The following query counts the winner and loser ID values in two separate queries which are then UNIONed together. There is no worry of double counting because a team cannot play against itself, rather it can only play against another unique team. The outer query sums the team counts.
SELECT t.id, COUNT(t.id) AS numMatches FROM (
SELECT winner AS id FROM Matches UNION ALL
SELECT loser AS id FROM Matches
) t GROUP BY t.id

why does profile query shows me NodeByLabelScan for a property which has a unique constraint in neo4j?

In my neo4j data, I have unique constraint set.
neo4j-sh (?)$ schema
Indexes
ON :Post(uuid) ONLINE (for uniqueness constraint)
Constraints
ON (post:Post) ASSERT post.uuid IS UNIQUE
However, when i do a profile on query, it seems search is being done by NodeByLabelScan
neo4j-sh (?)$ profile match (p:Post {uuid:"503cb957-9da0-490c-808d-48b64a1b1f64"}) return p;
+---+
| p |
+---+
+---+
0 row
12 ms
Compiler CYPHER 2.2
Planner COST
Filter
|
+NodeByLabelScan
+-----------------+---------------+------+--------+-------------+---------------------------+
| Operator | EstimatedRows | Rows | DbHits | Identifiers | Other |
+-----------------+---------------+------+--------+-------------+---------------------------+
| Filter | 1 | 0 | 2 | p | p.uuid == { AUTOSTRING0} |
| NodeByLabelScan | 1 | 1 | 2 | p | :Post |
+-----------------+---------------+------+--------+-------------+---------------------------+
Total database accesses: 4
Is there something I am missing here?
My neo4j version is 2.2.3.
Neo4j 2.2 introduced a cost based analyzer. I guess here Cypher has the opinion that a NodeByLabelScan with filtering is faster than a index query due to the small number of nodes.

SQL join statement with multiple columns

I have two tables like the following:
players:
id | name | location
1 | john | australia
2 | anne | u.s.
3 | jen | germany
games:
player | points | player2 | points2
john | 2 | anne | 1
anne | 1 | jen | 3
jen | 3 | john | 4
jen | 4 | anne | 1
I want the SQL statement to return each player's name, his or her location, and the total points each has accumulated through all games he or she participated in.
I tried to do a left join but I couldn't get this to work.
SELECT name, location, SUM(total_points) AS total_points
FROM (
SELECT name, location, COALESCE(SUM(points), 0) AS total_points
FROM players p
LEFT JOIN games g ON p.name = g.player
GROUP BY name, location
UNION ALL
SELECT name, location, COALESCE(SUM(points2), 0)
FROM players p
LEFT JOIN games g ON p.name = g.player2
GROUP BY name, location
) x
GROUP BY name, location
DEMO

Getting different (and incorrect) results runing the same cypher query on identical DB schemas

I'm running the following cypher query on two identical neo4j DB schemas:
START dave = node(7)
// dave's friend who lives and attends an event in the same city
MATCH dave-[:FRIEND]-friend-[:LIVES]->city-[:HOSTS]->event<-[:ATTENDS]-friend
RETURN dave.name, friend.name, city.name, event.name;
When I run the above query on the DB schema on my local server, I get correct results--a single path:
+----------------------------------------------------+
| dave.name | friend.name | city.name | event.name |
+----------------------------------------------------+
| "dave" | "adam" | "london" | "exhibition" |
+----------------------------------------------------+
In fact for each of the 4 persons node(4, 5, 6, 7), adam=node(4) is the only person who lives and attends an event in the same city.
However, when I run the same query here (on the exact same DB schema as on my local server) I'm getting the following incorrect result:
+----------------------------------------------------+
| dave.name | friend.name | city.name | event.name |
+----------------------------------------------------+
| "dave" | "adam" | "london" | "exhibition" |
| "dave" | "adam" | "london" | "exhibition" |
| "dave" | "bill" | "paris" | "seminar" | // bill doesn't attend seminar
+----------------------------------------------------+
For other persons instead of dave=node(7), the results here are also incorrect (extra paths that don't exist).
try to separate the match phase into 2, i have never used one parameter name 2 times in one match pattern:
except
MATCH dave-[:FRIEND]-friend-[:LIVES]->city-[:HOSTS]->event<-[:ATTENDS]-friend
use
MATCH dave-[:FRIEND]-friend-[:LIVES]->city-[:HOSTS]->event, event<-[:ATTENDS]-friend

Resources