Can I sum the count of two columns from two different tables? - sql

I'm trying to add together the counts of two different tables and group them by the same variable
Here is what I have so far:
SELECT a.storenumber,
Count (howmanytotal) AS total_counts_store
FROM (
SELECT month_counts.howmany,
new_counts.howmany) AS howmanytotal
from (
SELECT a.storenumber,
count (b.riid_) AS howmany
FROM $b$ b
INNER JOIN $a$ a
ON b.riid_=a.riid_
GROUP BY a.storenumber) month_counts
FROM (
SELECT a.storenumber,
count (c.riid_) AS howmany
FROM $c$ c
INNER JOIN $a$ a
ON c.riid_=a.riid_
GROUP BY a.storenumber) new_counts
ON month_counts.storenumber = new_counts.storenumber) theend
where I'm at now:
SELECT howmanytotal AS total_counts_store
FROM (
SELECT Count (howmany) AS howmanytotal)
FROM (
SELECT month_counts.howmany,
new_counts.howmany)
FROM (
SELECT a.storenumber,
count (b.riid_) AS howmany
FROM $b$ b
inner join $a$ a
ON b.riid_=a.riid_
GROUP BY a.storenumber) month_counts
UNION
(
SELECT count (c.riid_) AS howmany
FROM $c$ c
inner join $a$ a
ON c.riid_=a.riid_
GROUP BY a.storenumber) new_counts
ON month_counts.storenumber = new_counts.storenumber) ORDER BY $a$.storenumber
Getting this error: Error: java.sql.SQLSyntaxErrorException: ORA-00923: FROM keyword not found where expected
Please correct SELECT statement:

Join the subqueries:
select
storenumber,
month_counts.howmany as month_count,
new_counts.howmany as new_count,
month_counts.howmany + new_counts.howmany as total_count
from (...) month_counts
join (...) new_counts using (storenumber)
order by storenumber;
If it is possible for a storenumber to be missing from one of the subquery results, then outer join and use COALESCE or NVL to deal with the nulls. Here is a query with a full outer join, which is not available in MySQL, but in Oracle and many other DBMS.
select
storenumber,
month_counts.howmany as month_count,
new_counts.howmany as new_count,
nvl(month_counts.howmany, 0) + nvl(new_counts.howmany, 0) as total_count
from (...) month_counts
full outer join (...) new_counts using (storenumber)
order by storenumber;

Ending up using sum and union to complete. Thank you for your help.
SELECT storenumber,
SUM(howmany) AS howmanytotal
FROM (SELECT a.storenumber,
Count (b.riid_) AS howmany
FROM $b$ b
inner join $a$ a
ON b.riid_ = a.riid_
GROUP BY a.storenumber
UNION
SELECT a.storenumber,
Count (c.riid_) AS howmany
FROM $c$ c
inner join $a$ a
ON c.riid_ = a.riid_
GROUP BY a.storenumber)
GROUP BY storenumber
ORDER BY storenumber
This gave me a list of store ids and how many active subscribers we have at each store (taken from two separate tables)

Related

Counting number of rows resulting from a nested SQL select statement with a JOIN

I have the following SQL statement.
SELECT COUNT(a.id), a.project_id, p.is_recommended
FROM assessments a
INNER JOIN projects p ON p.id=a.project_id
WHERE p.is_recommended = 1
GROUP BY project_id
HAVING COUNT(a.id) >= 3
I would like to count the resulting number of rows.
If not for the INNER JOIN, all I'd have to do is something like this...
SELECT * FROM
(SELECT COUNT(id), project_id
FROM assessments
GROUP BY project_id
HAVING COUNT(id) >= 3) assessments
But how do I calculate the resulting number of rows if my statement has a JOIN? What syntax should I be using?
SELECT COUNT(*)
FROM (SELECT COUNT(a.id), a.project_id, p.is_recommended
FROM assessments a
INNER JOIN projects p ON p.id=a.project_id
WHERE p.is_recommended = 1
GROUP BY project_id
HAVING COUNT(a.id) >= 3
) AS counts

how to get single row in select count(*) in following query postgresql

select count(*) from ordrer
inner join ordrelinjer on ordrelinjer.ordrenr = ordrer.ordrenr
group by ordrelinjer.varetekst
This query return 4 rows, but I want to return 4 in count(*), how to do so?
You are getting 4 row because of group by. If you need distinct group count, you can try subquery.
select count(*)
from (
select count(*)
from ordrer
inner join ordrelinjer on ordrelinjer.ordrenr=ordrer.ordrenr
group by ordrelinjer.varetekst
) t
It seem that you're looking for the distinct number of values for ordrelinjer.varetekst, which would be:
select count(distinct ordrelinjer.varetekst)
from ordrer
join ordrelinjer on ordrelinjer.ordrenr = ordrer.ordrenr;
invoke without group by
select count(*) from ordrer inner join ordrelinjer on ordrelinjer.ordrenr=ordrer.ordrenr

Count and result from Inner Join

I have this query
SELECT COUNT(*) FROM (
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR )
which results in my case in
3
But I want to show also the result of the inner query
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
so the result would look like this
12345 34567 3
Which is the result of the selct plus the Count() result.
This would be easy using Windowed Aggregate Function:
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts,
SUM(Count(*)) OVER () -- Group sum
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
But AFAIK only Firebird 3 (currently in beta) supports those functions, so you need a more complicated query utilizing a Common Table Expression:
WITH cte AS
(
SELECT
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR,
Count(*) AS counts
FROM
ARTIKEL ART
INNER JOIN ARTSTLST ON ARTSTLST.OARTIKELLFDNR = ART.LFDNR
WHERE
ART.SUCHARTIKELNR = '22424'
GROUP BY
ART.LFDNR,
ARTSTLST.ARTIKELLFDNR
)
SELECT cte.*, (SELECT SUM(counts) FROM cte)
FROM cte

mysql query with double join

I have 3 tables, but I can only get to join another table count. See below.
The one below works like a charm, but I need to add another "count" from another table.
there is a 3rd table called "ci_nomatch" and contains a reference to ci_address_book.reference
which could have multiple entries (many on many) but I only need the count of that table.
so if ci_address_book would have an entries called "item1","item 2","item3"
and ci_nomatch would have "1,item1,user1","2,item1,user4"
I would like to have returned "2" for Item1 on the query.
Any ideas? I tried another join, but it tells me that the reference does not exist, while it does!
SELECT c.*, IFNULL(p.total, 0) AS matchcount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id=p.addressbook_id
ORDER BY matchcount DESC
LIMIT 0,15
You could subquery it directly in the select
SELECT c.*, IFNULL(p.total, 0) AS matchcount,
(SELECT COUNT(*) FROM ci_nomatch n on n.reference = c.reference) AS othercount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id=p.addressbook_id
ORDER BY matchcount DESC
LIMIT 0,15
#updated for comment. Including an extra column "(matchcount - othercount) AS deducted" would be best done by sub-querying.
SELECT *, matchcount - othercount AS deducted
FROM
(
SELECT c.* , IFNULL( p.total, 0 ) AS matchcount, (
SELECT COUNT( * ) FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference ) AS othercount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT( match_id ) AS total
FROM ci_matched_sanctions GROUP BY addressbook_id ) AS p
ON c.id = p.addressbook_id ORDER BY matchcount DESC LIMIT 0 , 15
) S

SQL Return only where more than one join

Not sure how to ask this as I'm a bit of a database noob,
What I want to do is the following.
table tb_Company
table tb_Division
I want to return companies that have more than one division and I don't know how to do the where clause.
SELECT dbo.tb_Company.CompanyID, dbo.tb_Company.CompanyName,
dbo.tb_Division.DivisionName FROM dbo.tb_Company INNER JOIN dbo.tb_Division ON
dbo.tb_Company.CompanyID = dbo.tb_Division.DivisionCompanyID
Any help or links much appreciated.
You'll need another JOIN where you only return companies having more than one division by using a GROUP BYand a HAVINGclause.
You can read up on grouping here
Groups a selected set of rows into a
set of summary rows by the values of
one or morecolumns or expressions. One
row is returned for each group.
Aggregate functions in the SELECT
clause list provide
information about each group instead
of individual rows.
SELECT dbo.tb_Company.CompanyID
, dbo.tb_Company.CompanyName
, dbo.tb_Division.DivisionName
FROM dbo.tb_Company
INNER JOIN dbo.tb_Division ON dbo.tb_Company.CompanyID = dbo.tb_Division.DivisionCompanyID
INNER JOIN (
SELECT DivisionCompanyID
FROM dbo.tb_Division
GROUP BY
DivisionCompanyID
HAVING COUNT(*) > 1
) d ON d.DivisionCompanyID = dbo.tb_Company.CompanyID
another alternative...
SELECT c.CompanyId, c.CompanyName, d.DivisionName
FROM tbl_Company c
INNER JOIN tbl_Division d ON c.CompanyId=d.DivisionCompanyId
GROUP BY c.CompanyId, c.CompanyName, d.DivisionName
HAVING COUNT(*) > 1
How about?
WITH COUNTED AS
(
SELECT C.CompanyID, C.CompanyName, D.DivisionName,
COUNT() OVER(PARTITION BY C.CompanyID) AS Cnt
FROM dbo.tb_Company C
INNER JOIN dbo.tb_Division D ON C.CompanyID = D.DivisionCompanyID
)
SELECT *
FROM COUNTED
WHERE Cnt > 1
With the other solutions (that join onto Division table twice), a single company/division can be returned under a heavy insert load.
If a row is inserted into the Division table between the time the first join occurs and the time the second join (with the group by/having) is evaluated, the first Division join will return a single row. However, the second one will return a count of 2.
How about...
SELECT dbo.tb_Company.CompanyID,
dbo.tb_Company.CompanyName,
FROM dbo.tb_Company
WHERE (SELECT COUNT(*)
FROM dbo.tb_Division
WHERE dbo.tb_Company.CompanyID =
dbo.tb_Division.DivisionCompanyID) > 1;