SQL Server : summarizing data - sql

I have this table:
CustomerID
Income
Date
Product
1
300
01/01/2015
A
1
300
01/01/2016
B
2
500
01/01/2016
A
2
300
01/01/2015
B
I want to see the list of CustomerID grouped by total income per year in separate columns.
I tried this code:
SELECT
CustomerID,
CASE
WHEN YEAR(DateofPurchase) = '2015'
THEN SUM(income)
ELSE 0
END AS '2015',
CASE
WHEN YEAR(DateofPurchase) = '2016'
THEN SUM(income)
ELSE 0
END AS '2016',
CASE
WHEN ProductID = 'A' THEN 'Yes' ELSE 'No' END AS 'If bought A'
FROM
exam
GROUP BY
CUSTOMERID, productID, YEAR(DateofPurchase)
Expected results:
CustomerID (UNIQUE), Total income 2015, Total income 2016, If bought prod. A(yes/no), if total income (2015+2016) is above 1K (yes/no)
Thank you

see: DBFIDDLE
--
SELECT
CustomerID,
SUM(Case when Year(DateofPurchase)='2015' then income else 0 end) as '2015',
SUM(Case when Year(DateofPurchase)='2016' then income else 0 end) as '2016',
max(Case when ProductID='A' then 'Yes' else 'No' end) as 'If bought A'
from exam
group by CUSTOMERID
You show group only on CUSTOMER_ID, because you want to see your results per CustomerId, ( and not per CustomerId, productID, year )
The SUM() should be put outside the CASE WHEN...END, because when the value of this case when is 0 you also need (or can) add it to the sum. This eliminates the need for putting Year in the GROUP BY.
The MAX(), on 'If bought A', is just a simple trick which works because 'Yes' is larger than 'No'
Finally, the second part of your question: (" if total income (2015+2016) is above 1K (yes/no)" I will leave this as an exercise to you, with the comment that studying the OVER-clause (see: SUM) might help solving it.

Related

How can I fetch total of Qty of Buy and Sale in month of July in single sql query

I want to find total buy and sell in single row for the specific month.
Below is the table
Month() function will help to group the month values.
SELECT
YEAR(TrDate) SaleYear,
MONTH(TrDate) SaleMonth,
SUM(CASE WHEN trType = 'B' THEN Qty END)) as TotalBuy,
SUM(CASE WHEN trType = 'S' THEN Qty END)) as TotalSale
FROM TableName
GROUP BY YEAR(TrDate), MONTH(TrDate)

How can I count total number of sales per month using a condition in SQL?

I searched the forum but couldn't find a problem like the one I have. I have a table called Journal Table and it has the following data:
A transaction is considered to be sales if the Quantity>0 otherwise it's a loan transaction. Now my question is how can I count the total number of transactions as Sales Per month.
Like:
Month | TotalSales
1 5
2 3
3 7
I tried the following but got the wrong output:
Select DISTINCT Month(date) AS 'Month',
(Select COUNT(TransactionID) from journalTable where Quantity>0)
AS 'Total Sales' from journalTable;
Here is a picture of the output:
The output is wrong as it counts the total of all months and shows it for each month. It should count each month's total and show it.
Just group by and conditionally sum.
select Month(date) as 'Month'
, sum(case when Quantity > 0 then 1 else 0 end) as 'Total Sales'
-- You can even add a count of loans at the same time.
, sum(case when Quantity <= 0 then 1 else 0 end) as 'Total Loans'
from journalTable
group by Month(date);
Something like this
SELECT MONTH(DATE) AS MONTH, COUNT(QUANTITY)CNTT
FROM TRANSACTIONS
WHERE QUANTITY > 0
GROUP BY MONTH(DATE)

Difference between COUNT and SUM within an Aggregate CASE statement

Full disclosure, I am learning and I have searched all over the internet and I just can't figure out my question.
I am working on an online class and was given the following example:
select
DATENAME(MONTH, DATEADD(MONTH, MONTH(OrderDate), -1)) AS 'Month',
SUM(CASE WHEN YEAR(OrderDate) = 2005 THEN 1 ELSE 0 END) AS Orders,
SUM(CASE YEAR(OrderDate) WHEN 2005 THEN Totaldue ELSE 0 END) AS 'Total Value'
from
sales.salesorderheader
group by Month(orderdate)
order by Month(orderdate) ASC
That returns the following results:
I understood that (I thought) so I began messing around with the code to further understand Case statements. Looking at the code I thought that the Orders field was essentially finding all the orders in a month, assigning a 1 to each one, and then adding them all up. Because each one was assigned a 1 I figured that I could change the SUM to COUNT and I would get the same results.
However, this code:
select
DATENAME(MONTH, DATEADD(MONTH, MONTH(OrderDate), -1)) AS 'Month',
COUNT(CASE WHEN YEAR(OrderDate) = 2005 THEN 1 ELSE 0 END) AS Orders,
SUM(CASE YEAR(OrderDate) WHEN 2005 THEN Totaldue ELSE 0 END) AS 'Total Value'
from
sales.salesorderheader
group by Month(orderdate)
order by Month(orderdate) ASC
Returns these results:
To try and break this down I created a query that would just look for the orders in January 2005 and count them.
SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE OrderDate >= '1/1/2005' AND OrderDate < '1/1/2005'
This returned 0. The same as the SUM query. I get that COUNT counts rows and SUM sums numbers in a column, but I just don't understand the results I'm getting. Could someone please explain why the count query is returning 2483 for January and not 0?
For COUNT 1 and 0 are the same. What you really need is NULL:
COUNT(ALL expression) evaluates expression for each row in a group and returns the number of nonnull values.
select
DATENAME(MONTH, DATEADD(MONTH, MONTH(OrderDate), -1)) AS 'Month',
COUNT(CASE WHEN YEAR(OrderDate) = 2005 THEN 1 ELSE NULL END) AS Orders,
SUM(CASE YEAR(OrderDate) WHEN 2005 THEN Totaldue ELSE 0 END) AS 'Total Value'
from sales.salesorderheader
group by Month(orderdate)
order by Month(orderdate) ASC;
Or even shorter(default ELSE is NULL so we could omit that part)
COUNT(CASE WHEN YEAR(OrderDate) = 2005 THEN 1 END) AS Orders,
Example:
SUM COUNT COUNT
2005 1 1 1
2006 0 0 NULL
2007 0 0 NULL
2005 1 1 1
===============================================
2 4 2
When you use count(*) you count ALL the rows. If you want to count how many orders you have, you have to use a column: eg: count(OrderDate). Try it
count example:
assume that your column has 3 value and column name is the order
2 ---------- 5 ---------- 4----- Null
now if you run
count (order)
it will return = 3 how many entries you have in the column without null
sum example:
2 ---------- 5 ---------- 4
now if you run
sum (order)
it will return = 2+5+4=11 its add all the entries

How to write this SQL without duplicating the customer?

I have a table that has customers listed every month with and active_indicator. For each customer, I want to pull the active indicator for just two months (Dec 2014 and Dec 2015), but when I write the below code, I get a table where each customer is listed twice. I know I can do another step to roll up the table to the customer level using max, but is there anyway to do this in one simple SQL query?
select distinct
customer
,case when date='2015-12-01' then active_indicator else 0 end as Dec2015_active_ind
,case when date='2014-12-01' then active_indicator else 0 end as Dec2014_active_ind
from monthly_account_cust
where date in ('2015-12-01', '2014-12-01')
order by customer
Pretty sure you are looking for something like this.
select
customer
, max(case when date = '2015-12-01' then active_indicator else 0 end) as Dec2015_active_ind
, max(case when date = '2014-12-01' then active_indicator else 0 end) as Dec2014_active_ind
from monthly_account_cust
where date in ('2015-12-01','2014-12-01')
group by customer
order by customer

Can I combine my two SQLite SELECT statements into one?

I have a SQLite table called posts. An example is shown below. I would like to calculate the monthly income and expenses.
accId date text amount balance
---------- ---------- ------------------------ ---------- ----------
1 2008-03-25 Ex1 -64.9 3747.56
1 2008-03-25 Shop2 -91.85 3655.71
1 2008-03-26 Benny's -100.0 3555.71
For the income I have this query:
SELECT SUBSTR(date, 0,7) "month", total(amount) "income" FROM posts
WHERE amount > 0 GROUP BY month ORDER BY date;
It works fine:
month income
---------- ----------
2007-05 4877.0
2007-06 8750.5
2007-07 8471.0
2007-08 5503.0
Now I need the expenses and I could of cause just repeat the first statement with the condition amount < 0, but I am wondering if there is an elegant way to get both income and expenses in one query?
Try something like this
select substr(date, 0,7) "Month",
total(case when a > 0 then a else 0 end) "Income",
total(case when a < 0 then a else 0 end) "Expenses"
from posts
group by month
Look into the UNION statement (bottom of the link). This will let you combine the results of two queries, generally in the form:
<SELECT_STATEMENT_1> UNION <SELECT_STATEMENT_2>
Not sure if SQL Lite supports CASE statements, but if it does you could do something like this.
SELECT SUBSTR(date, 0,7) "month"
, total(CASE WHEN Amount > 0 THEN Amount ELSE 0 END) "income"
, -1 * total(CASE WHEN Amount < 0 THEN Amount ELSE 0 END) "expenses"
FROM posts
GROUP BY month
ORDER BY date;