Oracle SQL query count, group by with an innerjoin? - sql

Basicly I have a bunch of Cars that belong to dealers and the dealers have a group.
The dealer table has the GROUP.ID and the Group table has the group name.
A Group has multiple dealers
So I want to count how many cars each group has.
I am using this atm
select
(select GROUP_NAME from "GROUP" where "GROUP".GROUP_ID = "DEALER"."GROUP_ID" ),
"DEALER"."GROUP_ID" as "DEALER GROUP ID",
"DEALER"."DEALER_NAME" as "DEALER DEALER NAME",
"CAR"."CAR_DEALER" as "CAR DEALER"
from
"CAR"
INNER JOIN
DEALER
ON
"DEALER"."DEALER_NAME" ="CAR"."CAR_DEALER"
I tried using group_by and count but I can't seem to get it to work

select
g.GROUP_NAME,
g.GROUP_ID,
count(*) as CAR_COUNT
from
GROUP g
inner join DEALER d on d.GROUP_ID = g.GROUP_ID
inner join CAR c on c.DEALER_ID = d.DEALERID
group by
/* Also add here all field you want to select from GROUP */
g.GROUP_NAME,
g.GROUPID

Related

Get all values from biggest group

I have a table of students and a table of books that they borrowed. I need to find a student who borrowed the most books and show titles of these books.
Currently I have a list of students and number of books that each student borrowed, sorted descending. I can get the student who borrowed the most by using Top 1.
SELECT TOP 1 Students.Name, Students.LastName, Count(Books.Title) AS BorrowedBooksCount
FROM (Meldunek INNER JOIN Students ON Meldunek.pesel = Students.pesel)
INNER JOIN Books
ON Students.pesel = Books.pesel
GROUP BY Students.Name, Students.LastName
ORDER BY Count(Books.Title) DESC;
How to show names of books of a student who borrowed the most books?
To get the student who borrowed the most books:
select top 1 m.pesel
from Meldunek as m
group by m.pesel
order by count(*) desc;
You can use this in a where clause for filtering. But you should take into account that multiple students might have the same value. So, use in rather than =:
where s.pesel in (select top 1 m.pesel
from Meldunek as m
group by m.pesel
order by count(*) desc
);
This logic can be inserted into your query, so you return only the top borrowing students.
The complete query looks like:
select s.Name, s.LastName, b.Title
from (Meldunek as m inner join
Students s
on m.pesel = s.pesel
) inner join
Books as b
on s.pesel = b.pesel
where s.pesel in (select top 1 m2.pesel
from Meldunek as m2
group by m2.pesel
order by count(*) desc
);

Count occurrences in many to many

In my database i have following tables:
Person (
id,
name,
agentId
)
Agent (
id,
title
)
Agency (
id,
name
)
AgentAgency (
id,
agentId,
agencyId
)
I need query that will get all info about Person -> Agents with extra attribute numberOfAgencies that will show number of agencies of each agent, AND i need to show one more attribute agencyName that will show me name of first or only agency that user have (i need it in case agent have only 1 agency).
I tried something like this but without any success.
SELECT *, COUNT (aa.agentId) as numberOfAgencies
FROM agentAgencies as aa
LEFT JOIN agent as a ON a.id = aa.agentId
LEFT JOIN agency as ag ON aa.agencyId= ag.id
LEFT JOIN person as p ON p.id = ag.personId
GROUP BY ag.id, aa.id, p.id, a.id
For example i expect response like this:
PersonName John, AgencyName Cool Agency, numberOfAgencies 4
SELECT
MAX(p.Name) PersonName,
count(a.id) NoOfAgencies,
MAX(a.name) AgencyName
FROM persons p
LEFT OUTER JOIN agent g ON g.Id=p.agentId
LEFT OUTER JOIN AgentAgency aa ON aa.agentId = g.Id
LEFT OUTER JOIN Agency a on a.id = aa.agencyId
GROUP BY a.Id

Count and group the number of times each town is listed in the table

SELECT PEOPLE.TOWNKEY, TOWN_LOOKUP.TOWN FROM PEOPLE
INNER JOIN TOWN_LOOKUP
ON PEOPLE.TOWNKEY = TOWN_LOOKUP.PK
ORDER BY TOWN
Current Table Output:
You are missing the group by clause entirely:
SELECT tl.town, COUNT(*)
FROM people p
INNER JOIN town_lookup ON p.townkey = tl.pk
GROUP BY tl.town
ORDER BY tl.town

Complicated SQL query

Does anyone have an idea about how to structure the following query:
Tables :
TBL_GAME id, name
TBL_CATEGORY id, name
LU_GAME_TO_CATEGORY gameid, catid
LU_GAME_TO_EVENT eventid, gameid
So, basically Categories have many games.
Events have many games.
I want to generate a report that shows the Categories listed by how many of its Games were used in Events. Ordered by the amount descending.
Is this possible ?
SELECT
c.id as catId,
c.name as catName,
g.id as gameId,
g.name as gameName,
sum(ge.INT_QUANTITY) as totalQuantities
FROM
TBL_CATEGORY as c,
TBL_GAME as g,
LU_GAME_TO_CATEGORY as gc,
LU_GAME_TO_EVENT as ge
WHERE
c.id = gc.catId AND
g.id = gc.gameId AND
g.id = ge.gameId
GROUP BY
c.id,
g.id
ORDER BY
totalQuantities desc,
c.name,
g.name
SELECT A.ID, SUM(D.INT_QUANTITY) AS YourSum
FROM TBL_CATEGORY A --Adapt your selected columns
INNER JOIN LU_GAME_TO_CATEGORY B ON A.id = B.catid
INNER JOIN TBL_CATEGORY C ON B.gameid = C.id
INNER JOIN LU_GAME_TO_EVENT D ON C.gameid = D.gameid
GROUP BY A.ID
ORDER BY YourSum DESC;
Here i don't adjust amount, because columns does not exist.
You must add Amount column in target table

How to count number of different items in SQL

Database structure:
Clubs: ID, ClubName
Teams: ID, TeamName, ClubID
Players: ID, Name
Registrations: PlayerID, TeamID, Start_date, End_date, SeasonID
Clubs own several teams. Players may get registered into several teams (inside same club or into different club) during one year.
I have to generate a query to list all players that have been registered into DIFFERENT CLUBS during one season. So if player swapped teams that were owned by the same club then it doesn't count.
My attempts so far:
SELECT
c.short_name,
p.surname,
r.start_date,
r.end_date,
(select count(r2.id) from ejl_registration as r2
where r2.player_id=r.player_id and r2.season=r.season) as counter
FROM
ejl_registration AS r
left Join ejl_players AS p ON p.id = r.player_id
left Join ejl_teams AS t ON r.team_id = t.id
left Join ejl_clubs AS c ON t.club_id = c.id
WHERE
r.season = '2008'
having counter >1
I can't figure out how to count and show only different clubs... (It's getting too late for clear thinking). I use MySQL.
Report should be like: Player name, Club name, Start_date, End_date
This is a second try at this answer, simplifying it to merely count the distinct clubs, not report a list of club names.
SELECT p.surname, r.start_date, r.end_date, COUNT(DISTINCT c.id) AS counter
FROM ejl_players p
JOIN ejl_registration r ON (r.player_id = p.id)
JOIN ejl_teams t ON (r.team_id = t.id)
JOIN ejl_clubs c ON (t.club_id = c.id)
WHERE r.season = '2008'
GROUP BY p.id
HAVING counter > 1;
Note that since you're using MySQL, you can be pretty flexible with respect to columns in the select-list not matching columns in the GROUP BY clause. Other brands of RDBMS are more strict about the Single-Value Rule.
There's no reason to use a LEFT JOIN as in your example.
Okay, here's the first version of the query:
You have a chain of relationships like the following:
club1 <-- team1 <-- reg1 --> player <-- reg2 --> team2 --> club2
Such that club1 must not be the same as club2.
SELECT p.surname,
CONCAT_WS(',', GROUP_CONCAT(DISTINCT t1.team_name),
GROUP_CONCAT(DISTINCT t2.team_name)) AS teams,
CONCAT_WS(',', GROUP_CONCAT(DISTINCT c1.short_name),
GROUP_CONCAT(DISTINCT c2.short_name)) AS clubs
FROM ejl_players p
-- Find a club where this player is registered
JOIN ejl_registration r1 ON (r1.player_id = p.id)
JOIN ejl_teams t1 ON (r1.team_id = t1.id)
JOIN ejl_clubs c1 ON (t1.club_id = c1.id)
-- Now find another club where this player is registered in the same season
JOIN ejl_registration r2 ON (r2.player_id = p.id AND r1.season = r2.season)
JOIN ejl_teams t2 ON (r2.team_id = t2.id)
JOIN ejl_clubs c2 ON (t2.club_id = c2.id)
-- But the two clubs must not be the same (use < to prevent duplicates)
WHERE c1.id < c2.id
GROUP BY p.id;
Here's a list of players for one season.
SELECT sub.PlayerId
FROM
(
SELECT
r.PlayerId,
(SELECT t.ClubID FROM Teams t WHERE r.TeamID = t.ID) as ClubID
FROM Registrations r
WHERE r.Season = '2008'
) as sub
GROUP BY PlayerId
HAVING COUNT(DISTINCT sub.ClubID) > 1
Here's a list of players and seasons, for all seasons.
SELECT PlayerId, Season
FROM
(
SELECT
r.PlayerId,
r.Season,
(SELECT t.ClubID FROM Teams t WHERE r.TeamID = t.ID) as ClubID
FROM Registrations r
) as sub
GROUP BY PlayerId, Season
HAVING COUNT(DISTINCT sub.ClubID) > 1
By the way, this works in MS SQL.
SELECT p.Name, x.PlayerID, x.SeasonID
FROM (SELECT DISTINCT r.PlayerID, r.SeasonID, t.ClubID
FROM Registrations r
JOIN Teams t ON t.ID = r.TeamID) x
JOIN Players p ON p.ID = x.PlayerID
GROUP BY p.rName, x.PlayerID, x.SeasonID
HAVING COUNT(*) > 1