I have two tables; Members and streams. I want to find the average number of streams for all members and then see which individual members (including first name) have streamed more than the average number of streams.
Currently i have this query which finds the average number of streams and the number of streams each member has;
select stream.m_ID, count(*), (select avg (count(*)) from stream group by stream.m_ID) from stream group by stream.m_ID;
I am struggling to find how to discard member who have a lower number of streams than the average number AND to join the member and stream table together
CREATE TABLE "M_5006677"."MEMBER"
( "M_ID" NUMBER(2,0),
"FNAME" VARCHAR2(15 BYTE) NOT NULL ENABLE,
"MNAME" VARCHAR2(15 BYTE),
"LNAME" VARCHAR2(15 BYTE) NOT NULL ENABLE,
"EMAIL" VARCHAR2(25 BYTE) NOT NULL ENABLE,
"R_DATE" DATE NOT NULL ENABLE,
"L_DATE" DATE,
CONSTRAINT "PK_M_ID" PRIMARY KEY ("M_ID")
CREATE TABLE "M_5006677"."STREAM"
( "STREAM_ID" NUMBER(2,0),
"SDATE" DATE,
"SPOSITION" NUMBER(5,2),
"F_ID" NUMBER(2,0) NOT NULL ENABLE,
"M_ID" NUMBER(2,0) NOT NULL ENABLE,
"LIVE" VARCHAR2(3 BYTE),
CONSTRAINT "PK_STREAM" PRIMARY KEY ("STREAM_ID")
CONSTRAINT "FK_F_ID" FOREIGN KEY ("F_ID") REFERENCE FILM
CONSTRAINT "FK_M_ID" FOREIGN KEY ("M_ID") REFERENCE MEMBER
I would use window functions. If you only want to count members who have ever streamed:
select m_id
from (select m_id, count(*) as cnt, avg(count(*)) over () as avg_overall
from streams
group by m_id
) s
where cnt > avg_overall;
If you want to count members who never streamed:
select m_id
from (select m_id, count(*) as cnt, avg(count(s.m_id)) over () as avg_overall
from members m left join
streams s
on m.m_id = s.m_id
group by m_id
) s
where cnt > avg_overall;
This would work for sql server:
select stream.m_ID, count(*), (select avg (count(*)) from stream group by stream.m_ID) from stream group by stream.m_ID
having count(*) < (select avg (count(*)) from stream group by stream.m_ID)
If you want also get data about members then you should include M_ID into your query so you can join with members table like that:
select stream.m_ID, M_ID, count(*), (select avg (count(*)) from stream group by stream.m_ID) from stream group by stream.m_ID ,M_ID
having count(*) < (select avg (count(*)) from stream group by stream.m_ID)
after that you can join on M_ID with Members table:
select FNAME from Member m
join (select stream.m_ID, M_ID, count(*), (select avg (count(*)) from stream
group by stream.m_ID) from stream group by stream.m_ID ,M_ID
having count(*) < (select avg (count(*)) from stream group by
stream.m_ID)) X on m.M_ID = X.M_ID
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.