rahul
rahul

Reputation: 2279

run count query for each account

I am working on a some extensions to Gerrit. I have the following query to get the TOTAL COMMITS, TOTOAL REVIEW COMMENTS...etc for a particular ACCOUNT_ID from the gerrit DB.

with 
  changeids as
    (select change_id from PATCH_SETS where UPLOADER_ACCOUNT_ID=1001961),
  patchcommentstoothers as
    (select count(*) c from patch_comments where AUTHOR_ID!=1001961 AND Change_id in (select change_id from changeids)),
  ownerchanges as
    (select count(*) c from changes where owner_account_ID=1001961 and OPEN='Y'),
  changemessages as
    (select count(*) c from change_messages where AUTHOR_ID=1001961 and change_id not in (select change_id from changeids))
select pcto.c TOT_PATCH_COMMENTS, oc.c TOT_CHANGES, cm.c TOT_CHANGE_MESSAGES
from patchcommentstoothers pcto, ownerchanges oc, changemessages cm;

Now with the above query I can get the three counts for one user. I want to run the above query for all ACCOUNT_ID's. Something like run this query for each account (not just for 1001961 here) and get back all the records in one go for all accounts.

ACCOUNT table has the following columns:

"REGISTERED_ON" TIMESTAMP (6) NOT NULL ENABLE,
"FULL_NAME"       VARCHAR2(255 BYTE),
"PREFERRED_EMAIL" VARCHAR2(255 BYTE),
"CONTACT_FILED_ON" TIMESTAMP (6),
"MAXIMUM_PAGE_SIZE"   NUMBER(6,0) DEFAULT 0,
"SHOW_SITE_HEADER"    CHAR(1 BYTE) DEFAULT 'N',
"USE_FLASH_CLIPBOARD" CHAR(1 BYTE) DEFAULT 'N',
"DOWNLOAD_URL"        VARCHAR2(20 BYTE),
"DOWNLOAD_COMMAND"    VARCHAR2(20 BYTE),
"COPY_SELF_ON_EMAIL"  CHAR(1 BYTE) DEFAULT 'N',
"DATE_FORMAT"         VARCHAR2(10 BYTE),
"TIME_FORMAT"         VARCHAR2(10 BYTE),
"INACTIVE"            CHAR(1 BYTE) DEFAULT 'N',
"ACCOUNT_ID"          NUMBER(11,0) DEFAULT 0

I would prefer not to use procedures.

P.S. - I suck at Oracle SQL.

Upvotes: 1

Views: 188

Answers (1)

MatBailie
MatBailie

Reputation: 86765

with
  changeids
as
(
  select
    UPLOADER_ACCOUNT_ID,
    change_id
  from
    PATCH_SETS
  group by
    UPLOADER_ACCOUNT_ID,
    change_id
),
  patchcommentstoothers
as
(
  select
    changeids.UPLOADER_ACCOUNT_ID,
    count(*) c
  from
    changeids
  inner join
    patch_comments
      ON  changeids.UPLOADER_ACCOUNT_ID != patch_comments.AUTHOR_ID
      AND changeids.change_id            = patch_comments.change_id
  group by
    changeids.UPLOADER_ACCOUNT_ID 
),
  ownerchanges
as
(
  select
    owner_account_ID,
    count(*) c
  from
    changes
  where
    OPEN='Y'
  group by
    owner_account_ID
),
  changemessages
as
(
  select
    change_messages.AUTHOR_ID,
    count(*) c
  from
    change_messages
  left join
    changeids
      on  changeids.UPLOADER_ACCOUNT_ID = change_messages.AUTHOR_ID
      AND changeids.change_id           = change_messages.change_id
  where
    changeids.change_id IS NULL
  group by
    change_messages.AUTHOR_ID
)

select
  accounts.ACCOUNT_ID,
  pcto.c   TOT_PATCH_COMMENTS,
  oc.c     TOT_CHANGES,
  cm.c     TOT_CHANGE_MESSAGES
from
  accounts
LEFT JOIN
  patchcommentstoothers pcto
    ON accounts.ACCOUNT_ID = pcto.UPLOADER_ACCOUNT_ID
LEFT JOIN
  ownerchanges          oc
    ON accounts.ACCOUNT_ID = oc.owner_account_ID
LEFT JOIN
  changemessages        cm
    ON accounts.ACCOUNT_ID = cm.AUTHOR_ID
;

The CTEs now calculate the values for every user.

The final select assumes that you have a user table that lists all of your users.

If you filter the final query by user, the CTEs will only calculate the results for the users in the final results.

Upvotes: 1

Related Questions