简体   繁体   中英

SQL joining multiple tables with count

Description of tables:

Table Members:
  id
  name
  status

Table Memberships:
  id
  date_start
  date_end
  date_added
  cost
  member_id
  status
  membership_type

Table Things:
  id
  name
  quantity
  member_id
  status

With following query i wanted to get table/view that would display me "MEMBERSHIP" for each "MEMBER" that will have sum of "THINGS" in the last column for each "MEMBER".

Logic is this: "MEMBERS" is one member per record, Each "MEMBER" can have multiple "MEMBERSHIPS" and each "MEMBER" can have multiple "THINGS" records.

However, following query returns me sum of quantity of things multiplied with the number of memberships that each user have.

  select
  memberships.id,
  memberships.member_id,
  members.name,
  members.status,
  memberships.membership_type,
  memberships.date_start,
  memberships.date_end,
  memberships.date_added,
  memberships.cost,
  memberships.status
  sum(things.quantity) as quantity
  from memberships
  right join members on memberships.member_id = members.id
  right join things on things.member_id = members.id
  where NOW() between memberships.date_start and memberships.date_end
  and memberships.status = 1
  and things.status = 1
  and members.status = 1
  group by members.id, memberships.member_id

You need to calculate each records on separate subquery in order for you to achieve correct results. If you join the tables and calculate it directly, you will have invalid result because members can have multiple records on membership table as well as multiple things on Things table.

SELECT  a.*,
        COALESCE(b.totalMembership, 0) totalMembership,
        COALESCE(c.TotalThings, 0) TotalThings
FROM    Members a
        LEFT JOIN
        (
            SELECT  member_id, COUNT(*) totalMembership
            FROM    Memberships 
            GROUP   BY member_ID
        ) b ON a.ID = b.member_ID
        LEFT JOIN 
        (
            SELECT  member_ID, SUM(quantity) TotalThings
            FROM    Things
            GROUP   BY member_ID
        ) c ON a.ID = c.member_ID

As i was experimenting, i find out another work around with no need for sub queries and it's 100% useful for similar scenarios.

I just added a column in select that is being calculated like this:

(sum(things.quantity) DIV count(distinct memberships.id)) as quantity

And, voilà, it works :)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM