SQL Query - using COUNT - sql

I have a database structure like this:
Table - lodges
LodgeID (PK)
Lodge
etc
Table - scores
ScoreID (PK)
Score
CategoryID
LodgeID (FK)
I'm trying to return results in the form:
LodgeID, Lodge, Category, Number of Scores in that Category, Average Score in that Category
So for example, if I had:
lodges
LodgeID, Lodge
1, Lodge One
2, Lodge Two
scores
ScoreID, Score, CategoryID, LodgeID
1, 3, 101, 1
2, 5, 101, 1
3, 7, 101, 1
4, 10, 102, 2
5, 20, 102, 2
6, 30, 102, 2
7, 40, 102, 2
I'd like to return:
1, Lodge One, 3, 5
2, Lodge Two, 4, 25
I've been trying things like:
SELECT COUNT(ScoreID) as scoreCount, AVG(Score) as AverageScore, Lodge
FROM scores_temp
INNER JOIN lodges_temp ON scores_temp.LodgeID = lodges_temp.LodgeID
SELECT lodges_temp.LodgeID, Lodge, COUNT(ScoreID) as scoreCount, AVG(Score) as AverageScore FROM lodges_temp INNER JOIN scores_temp ON lodges_temp.LodgeID = scores_temp.LodgeID
Without any success. Any pointers would be much appreciated.

Try this
SELECT COUNT(ScoreID) as scoreCount, AVG(Score) as AverageScore, Lodge
FROM scores_temp
INNER JOIN lodges_temp ON scores_temp.LodgeID = lodges_temp.LodgeID
GROUP BY Lodge

You are missing a group by clause:
SELECT COUNT(ScoreID) as scoreCount, AVG(Score) as AverageScore, Lodge
FROM scores
INNER JOIN lodges ON scores.LodgeID = lodges.LodgeID
GROUP BY lodge

Related

counting rows where column value match, over all distinct column values - sql

I'm using SQL and this is my goal:
Starting table:
anime_uid, reviewer, score
1, james, 8
1, john, 7
2, sam, 5
1, alice, 7
3, john, 5
2, alice, 4
My goal is to know how many times an anime was reviewed, and what is the avg score. meaning i need to have something like this:
anime_uid, times_reviewed, avg_score
1, 3, 7.33
2, 2, 4.5
3, 1, 5
I can't seem to deconstruct the query to sub-queries to complete this task, would love your help! Thanks!
you can try this query:
SELECT
anime_uid,
COUNT(DISTINCT reviewer) as times_reviewed,
AVG(score) as avg_score
FROM table
GROUP BY anime_uid

Create edges list with weights from flat list using SQL?

In SQL Server I have an input list (like below), where the groups are the edges of future graph:
group 1, user 1
group 1, user 2
group 1, user 3
group 2, user 1
group 2, user 3
group 3, user 1
group 4, user 4
How to create a list of edges, where the weights will be the number of common participants between groups, using SQL tools?
group 1, group 2, 2
group 1, group 3, 1
group 2, group 3, 1
You an use a self join and aggregation:
select g1.groupid, g2.groupid, count(*)
from graph g1 join
graph g2
on g1.userid = t2.userid and g1.groupid < g2.groupid
group by g1.groupid, g2.groupid;

Count Childs and partition by GrandParent, that resides in an unpivoted hierarchy

I want to show the COUNT on every row how many BuildingID's there are within the MainGroundID's, while having to deal with a parent-child hierarchy that is unpivoted.
Unfortunately there is no logic within the way the GroundID and MainGroundID's are written (although it looks that way in my example, since I made an example dataset).
PMEBuilding
BuildingID, GroundID
1, 100
2, 100
3, 101
4, 201
5, 201
6, 201
7, 202
In reality the above table has 34K rows and 80+ fields.
The GroundID from the table above is N:1 to the table below via GroundID.
Within the PMEGroudn table Some GroundID's refer to a certain MainGroundID, which in turn also refer to Parents higher up in the hierarchy. The 'GrandParents' are those that have a NULL value as GroundID.
PMEGround
GroundID, MainGroundID
1, NULL --GrandParent
10, 1
100, 10
101, 10
2, NULL --GrandParent
20, 2
201, 20
202, 20
In reality the above table has 2K rows of which around 500 'GrandParents'.
I want this to be the end result:
MainGroundID MainGroundBuildingCount
1, 3
2, 7
The following code is what I used so far, but it doesn't work entirely yet:
;WITH UNPIVOT_HIERARCHY AS (
SELECT GROUNDID
,MAINGROUNDID
,PathID = CAST(GROUNDID AS VARCHAR(MAX))
FROM PMEGROUND
WHERE NULLIF(MainGroundID, '') IS NULL
UNION All
SELECT GROUNDID = r.GROUNDID
,MAINGROUNDID = r.MAINGROUNDID
,PathID = p.PathID+CONCAT(',',CAST(r.GROUNDID AS VARCHAR(MAX)))
FROM PMEGROUND r
JOIN UNPIVOT_HIERARCHY p ON r.MAINGROUNDID = p.GROUNDID
)
SELECT
B.Lvl3 AS 'MainGroundID' --This is the GrandParent, which works fine
,COUNT(PMEBUILDING.GROUNDID) OVER (PARTITION BY B.Lvl3) AS 'MainGroundCountBuildings'
FROM PMEGROUND
LEFT JOIN UNPIVOT_HIERARCHY
ON UNPIVOT_HIERARCHY.GROUNDID = PMEGROUND.GROUNDID
LEFT JOIN PMEBUILDING
ON PMEBUILDING.GROUNDID = PMEGROUND.GROUNDID
CROSS Apply (
SELECT Lvl1 = xDim.value('/x[3]','varchar(50)')
,Lvl2 = xDim.value('/x[2]','varchar(50)')
,Lvl3 = xDim.value('/x[1]','varchar(50)')
,Lvl4 = xDim.value('/x[4]','varchar(50)')
FROM ( VALUES (CAST('<x>' + REPLACE(PathID,',','</x><x>')+'</x>' AS xml))) B(xDim)
) B
GROUP BY B.Lvl3, PMEBUILDING.GROUNDID
Without the GROUP BY it gives duplicate MainGroundIDs, but the correct count.
With the GROUP BY it still gives duplicate MainGroundIDs but less, but the count is messed up now.
I want this to be the end result:
MainGroundID MainGroundBuildingCount
1, 3
2, 7
Don't you mean the end result should be?
MainGroundID MainGroundBuildingCount
1, 3
2, 4
Assuming, based on the given data, that there are 3 levels of hierarchy and PMEBuilding.GroundID contains only grandchildren I would use the following to achieve the end result:
select
gp.GroundID, count(distinct b.BuildingID)
from PMEGround gp
join PMEGround p on p.MainGroundID = gp.GRoundID
join PMEGround c on c.MainGroundID = p.GRoundID
join PMEBuilding b on b.GroundID = c.GroundID
where gp.MainGroundID is null
group by gp.GroundID
order by 1

SQL 2 Tables, get counts on first, group by second

I'm working in MS Access 2003.
I have Table with records of that kind of structure:
ID, Origin, Destination, Attr1, Attr2, Attr3, ... AttrX
for example:
1, 1000, 1100, 20, M, 5 ...
2, 1000, 1105, 30, F, 5 ...
3, 1001, 1000, 15, M, 10 ...
...
I also have table which has Origin And Destination Codes Grouped
Code, Country, Continent
1000, Albania, Europe
1001, Belgium, Europe
...
1100, China, Asia
1105, Japan, Asia
...
What I need is to get 2 tables which would count records based on criteria related to attributes I specify but grouped by:
1. Origin Continent and Destination Continent
2. Origin Continent and Destination Country
for example:
Case 1.
Origin, Destination, Total, Females, Males, Older than 20, Younger than 20, ...
Europe, China, 300, 100, 200, 120, 180 ...
Europe, Japan, 150, 100, 50, ...
...
Case 2.
Origin, Destination, Total, Females, Males, Older than 20, Younger than 20, ...
Europe, Asia, 1500, 700, 800 ...
Asia, Europe, 1200, ...
...
Can that be done in the way so I could add more columns/criteria easily enough?
Case 1:
select count(1) as total ,t2.continent,t3.country,t1.attr1,t1.attr2,t1.attr3 ... t1.attrX from table1 t1
join table2 t2 on t1.origin = t2.code
join table3 t3 on t1.destination = t3.code
group by t2.continent,t3.country,t1.attr1,t1.attr2,t1.attr3 ... t1.attrX
order by total desc
Case 2:
select count(1) as total ,t2.continent,t3.continent,t1.attr1,t1.attr2,t1.attr3 ... t1.attrX from table1 t1
join table2 t2 on t1.origin = t2.code
join table3 t3 on t1.destination = t3.code
group by t2.continent,t3.continent,t1.attr1,t1.attr2,t1.attr3 ... t1.attrX
order by total desc
You can join queries with queries, so this is a crosstab for Male/Female (attr2)
TRANSFORM Count(Data.ID) AS CountOfID
SELECT Data.Origin, Data.Destination, Count(Data.ID) AS Total
FROM Data
GROUP BY Data.Origin, Data.Destination
PIVOT Data.Attr2;
This is ages:
TRANSFORM Count(Data.ID) AS CountOfID
SELECT Data.Origin, Data.Destination, Count(Data.ID) AS Total
FROM Data
GROUP BY Data.Origin, Data.Destination
PIVOT Partition([Attr1],10,100,10);
This combines the two:
SELECT Ages.Origin, Ages.Destination, Ages.Total,
MF.F, MF.M, Ages.[10: 19], Ages.[20: 29], Ages.[30: 39]
FROM Ages, MF;
As you can see, this could be easier to manage in VBA.

SQL Server query question (Count maybe?)

I have the following query:
SELECT A.shipment_id
,B.box_id
,A.shipment_status
FROM shipments A
join boxes B on A.shipment_id = B.shipment_id
where A.shipment_status = 2
Group by B.box_id, A.shipment_id, A.shipment_status
That returns a result set that looks like this:
shipment_id, box_id, shipment_status
101, boxA, 2
101, boxB, 2
101, boxC, 2
102, box101, 2
102, box102, 2
103, boxA1, 2
103, boxA2, 2
I would like to return something like this instead (showing a total amount of boxes per shipment):
shipment_id, box count, shipment_status
101, 3, 2
102, 2, 2
103, 2, 2
How would I achieve this?
Thanks!
SELECT A.shipment_id
,COUNT(*) AS boxcount
,A.shipment_status
FROM shipments A
join boxes B on A.shipment_id = B.shipment_id
where A.shipment_status = 2
Group by A.shipment_id, A.shipment_status
Just need to remove the box_id from the GROUP BY and use COUNT, as you said in your title.
Try this:
SELECT A.shipment_id
, count(1)
, A.shipment_status
FROM shipments A
join boxes B on A.shipment_id = B.shipment_id
where A.shipment_status = 2
Group by A.shipment_id, A.shipment_status