In SQL, how to you join multiple aggregate queries (count or sum specifically)? - sql

I have a table that has the total number of different items per person. I am trying to create a new table that counts the number of people with a total of 0, 1, 2, 3, 4, 5, 6, and 7+ items grouped by company and year. I think I have individual queries that accomplish this task, but I can't get a join to work in order to fill the new table. The individual queries that seem to accomplish what I am trying to do are:
SELECT
Company,
YEAR(Date) as Year,
COUNT(*) as items0_Count
FROM table
WHERE items_total = 0
GROUP BY Company, YEAR(Date)
ORDER BY Company, YEAR(Date)
SELECT
Company,
YEAR(Date) as Year,
COUNT(*) as items1_Count
FROM table
WHERE items_total = 1
GROUP BY Company, YEAR(Date)
ORDER BY Company, YEAR(Date)
I would obviously have that same query 8 times with only the where statement changing in order to generate the counts for each case, but only included two here to keep the question short. Hope this makes sense, and thank you in advance for your help!

Use conditional aggregation:
SELECT Company, YEAR(Date) as Year,
SUM(CASE WHEN items_total = 0 THEN 1 ELSE 0 END) as items0_Count,
SUM(CASE WHEN items_total = 1 THEN 1 ELSE 0 END) as items2_Count
FROM table
GROUP BY Company, YEAR(Date)
ORDER BY Company, YEAR(Date);
You can add additional columns for whatever item counts you want.

Union all/ union the two queries you have. You'll get the desired else follow #GordonLinoff's answer.
Also as an easy way try this below
SELECT
Company,
YEAR(Date) as Year,
COUNT(*) as items0_Count
FROM table
WHERE items_total in (1,0)
GROUP BY Company, YEAR(Date)
ORDER BY Company, YEAR(Date)

Related

Combine different results of "group by" queries in the same table

I need to make some comparation between 2 years: sales by product, sales by category, etc.
How can I have this in one table having 3 columns:
first column = product, category, etc
second column = sales in 2021
third column = sales in 2022
Sample of queries that must be combined in one single table as the one below
select product_code, sum(amount)
from product
where year = '2021'
group by product_code
select product_code, sum(amount)
from product
where year = '2022'
group by product_code
select category_code, sum(amount)
from category
where year = '2021'
group by category_code
select category_code, sum(amount)
from category
where year = '2022'
group by category_code
Please, see the final table
[1]: https://i.stack.imgur.com/smF7h.png
NOTE!
If for instance in 2021 there was no "product D", it will be 0 for "Sales_2021" or the "product A" is no longer present in 2022, it will be 0 for "Sales_2022".
Thank you
You need two things here:
Conditional aggregation (a CASE expression inside the aggregation function) in order to get 2021 and 2022 in one go.
A union of two intermediate result sets (product figures UNION ALL category figures).
And as any table - and a query result is again a table - is unordered, we need an ORDER BY at last to get products first and categories second and also the products ordered alphabetically and the categories, too.
The complete query:
select category_or_product, sales_2021, sales_2022
from
(
select
product_code as category_or_product,
sum(case when year = 2021 then amount else 0 end) as sales_2021,
sum(case when year = 2021 then amount else 0 end) as sales_2022,
1 as product_first
from product
group by product_code
union all
select
category_code as category_or_product,
sum(case when year = 2021 then amount else 0 end) as sales_2021,
sum(case when year = 2021 then amount else 0 end) as sales_2022,
2 as product_first
from category
group by category_code
) unioned
order by product_first, category_or_product;

How to get the asked columns for each customers

I have this table called table a
I need to get the CustomerID, sum(Income) of 2015, sum(Income) of 2016, did he ever bought productId A (boolean), is the total sum(income)> 1000 (boolean), number of total InvoiceID
all that in one query and the results should be with 1 row per customer.
please help I don't even know how to start!
This is basically conditional aggregation:
select customerid,
sum(case when extract(year from date) = 2015 then sales end) as sales_2015,
sum(case when extract(year from date) = 2016 then sales end) as sales_2016,
max( product = 'A' ) as ever_bought_a,
sum(income) > 1000 as sum_exceeds_1000,
count(*) as num_invoices
from t
group by customerid;
You haven't specified a database, so this is really psuedocode. You'll need to adapt it for your particular database.

Group by 4 different levels and total numeric field

I'm querying a financial database that has the following information:
Company ID
Fiscal Year
Fiscal Period
Account
Amount
I want to group the data by the first four fields and show a grouped total of amount.
I tried the GROUP BY but that doesn't seem to work.
In my screenshot, I'm trying to get rows 1-10 to show as one line, as all the information is the same except for the amount.
Here's my code:
SELECT Erp.GLJrnDtl.Company, Erp.GLJrnDtl.FiscalYear,
Erp.GLJrnDtl.FiscalPeriod, Erp.GLJrnDtl.BalanceAcct,
Erp.GLJrnDtl.BookDebitAmount - Erp.GLJrnDtl.BookCreditAmount AS Amount
FROM Erp.GLJrnDtl INNER JOIN
Erp.GLPeriodBal ON Erp.GLJrnDtl.Company =
Erp.GLPeriodBal.Company AND Erp.GLJrnDtl.FiscalYear =
Erp.GLPeriodBal.FiscalYear AND Erp.GLJrnDtl.FiscalPeriod =
Erp.GLPeriodBal.FiscalPeriod AND
Erp.GLJrnDtl.BalanceAcct =
Erp.GLPeriodBal.BalanceAcct
WHERE (Erp.GLJrnDtl.FiscalYear >= 2018) AND (Erp.GLJrnDtl.Company
= N'011') and (Erp.GLJrnDtl.SegValue1 = N'310050')
GROUP BY Erp.GLJrnDtl.Company, Erp.GLJrnDtl.FiscalYear,
Erp.GLJrnDtl.FiscalPeriod, Erp.GLJrnDtl.BalanceAcct,
Erp.GLJrnDtl.PostedDate, Erp.GLJrnDtl.BookDebitAmount,
Erp.GLJrnDtl.BookCreditAmount, Erp.GLJrnDtl.SegValue1,
Erp.GLPeriodBal.BalanceAmt
select company_id, fiscal_year, fiscal_period, account, sum(amount)
from table group by company_id, fiscal_year, fiscal_period, account
You need to leave out the field you want to aggregate outside the group by line
Please explain why this does not do what you want:
select Company_ID, Fiscal_Year, Fiscal_Period, Account, sum(Amount)
from t
group by Company_ID, Fiscal_Year, Fiscal_Period, Account;
This is the "obvious" query. The query in the image is much more complicated.

Multiple counts in one SQL query with grouping

I want to run a query to get a count of open incident and closed incidents grouped by year and month, the below query works fine without the grouping, but once I add the group it will not work!
SELECT (SELECT COUNT(*) AS Opened FROM Incidents) AS Total
(SELECT COUNT(*) AS Solved FROM Incidents WHERE (MONTH(Closedate)=MONTH(Opendate))) AS Solved
GROUP BY YEAR(Incidents.Opendate)
You can use single a SELECT statement with CASE expression
SELECT YEAR(Incidents.Opendate) AS [Year],
MONTH(Incidents.Opendate) AS [Month],
COUNT(*) AS Total,
SUM(CASE WHEN MONTH(Closedate) = MONTH(Opendate) THEN 1 ELSE 0 END) AS Solved
FROM Incidents
GROUP BY YEAR(Incidents.Opendate), MONTH(Incidents.Opendate)
Try:
SELECT
(SELECT COUNT(*) FROM Incidents) as Total ,
(SELECT COUNT(*) FROM Incidents WHERE (Month(Closedate)=MONTH(Opendate))) as Solved
FROM Incidents
Group by YEAR(Incidents.Opendate)
I have managed to solve it, below is the query
select COUNT(CASE WHEN Month(Closedate)=Month(Opendate) then 1 else null end) AS closed,COUNT(*) AS Opened
from incidents
Group by Year(Opendate), Month(Opendate)
Order by Year(Opendate), Month(Opendate)

adding a calculated/virtual column to an existing query

My query returns a sales column total for each month and a purchases total for each month, for certain categories.
SELECT theMonth,
sum(Sales) as sumSales,
sum(Saleswotax) as sumSaleswotax,
sum(Purchases) as sumPurchases,
sum(Purchaseswotax) as sumPurchaseswotax
FROM ( SELECT date_format(saledate, '%Y-%m') AS theMonth,
sales.cost as Sales,
ROUND(sales.cost*0.85, 2) AS Saleswotax,
0 AS Purchases,
0 AS Purchaseswotax
FROM sales, products
WHERE sales.product = products.name
AND category='Food'
UNION ALL
SELECT date_format(purchasedate, '%Y-%m') AS theMonth,
0 as Sales,
0 AS Saleswotax,
purchases.cost as Purchases,
ROUND(purchases.cost*0.85, 2) AS Purchaseswotax,
FROM purchases) AS all_costs
group by theMonth
I am trying to return a column(that does not actually exist in the table) in my query that is just a calculation of an existing table., ie the saleswotax and purchaseswotax columns.
I am using a function, and returning it AS a name...why is it not working?
In the union, you used 0 as sales and purchases columns, but didn't also do that for -wotax columns. They need to match up for the union to work properly (I think you know that, since you did it for Sales and Purchases).
You need to remove the comma after AS Purchasewotax in the latter half of the UNION:
SELECT theMonth,
sum(Sales) as sumSales,
sum(Saleswotax) as sumSaleswotax,
sum(Purchases) as sumPurchases,
sum(Purchaseswotax) as sumPurchaseswotax
FROM ( SELECT date_format(saledate, '%Y-%m') AS theMonth,
sales.cost as Sales,
ROUND(sales.cost*0.85, 2) AS Saleswotax,
0 AS Purchases,
0 AS Purchaseswotax
FROM sales, products
WHERE sales.product = products.name
AND category='Food'
UNION ALL
SELECT date_format(purchasedate, '%Y-%m') AS theMonth,
0 as Sales,
0 AS Saleswotax,
purchases.cost as Purchases,
ROUND(purchases.cost*0.85, 2) AS Purchaseswotax
FROM purchases) AS all_costs
GROUP BY theMonth
Last time when I saw, there was no declarative support for computed fields in MySQL.
You would have to either add computed columns to your table and fill them using an UPDATE/INSERT trigger. Or create Views with additional computed columns.