How to write this SQL without duplicating the customer? - sql

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

Related

SQL Server : summarizing data

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.

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)

SQL - Dividing aggregated fields, very new to SQL

I have list of line items from invoices with a field that indicates if a line was delivered or picked up. I need to find a percentage of delivered items from the total number of lines.
SALES_NBR | Total | Deliveryrate
1 = Delivered 0 = picked up from FULFILLMENT.
SELECT SALES_NBR,
COUNT (ITEMS) as Total,
SUM (case when FULFILLMENT = '1' then 1 else 0 end) as delivered,
(SELECT delivered/total) as Deliveryrate
FROM Invoice_table
WHERE STORE IN '0123'
And SALE_DATE >='2020-02-01'
And SALE_DATE <='2020-02-07'
Group By SALES_NBR, Deliveryrate;
My query executes but never finishes for some reason. Is there any easier way to do this? Fulfillment field does not contain any NULL values.
Any help would be appreciated.
I need to find a percentage of delivered items from the total number of lines.
The simplest method is to use avg():
select SALES_NBR,
avg(fulfillment) as delivered_ratio
from Invoice_table
where STORE = '0123' and
SALE_DATE >='2020-02-01' and
SALE_DATE <='2020-02-07'
group by SALES_NBR;
I'm not sure if the group by sales_nbr is needed.
If you want to get a "nice" query, you can use subqueries like this:
select
qry.*,
qry.delivered/qry.total as Deliveryrate
from (
select
SALES_NBR,
count(ITEMS) as Total,
sum(case when FULFILLMENT = '1' then 1 else 0 end) as delivered
from Invoice_table
where STORE IN '0123'
and SALE_DATE >='2020-02-01'
and SALE_DATE <='2020-02-07'
group by SALES_NBR
) qry;
But I think this one, even being ugglier, could perform faster:
select
SALES_NBR,
count(ITEMS) as Total,
sum(case when FULFILLMENT = '1' then 1 else 0 end) as delivered,
sum(case when FULFILLMENT = '1' then 1 else 0 end)/count(ITEMS) as Deliveryrate
from Invoice_table
where STORE IN '0123'
and SALE_DATE >='2020-02-01'
and SALE_DATE <='2020-02-07'
group by SALES_NBR

Transact SQL - Table with different Record types requiring calculation

I have a table of invoices and Record_Types that I need to reconcile to open invoice report. I have the process down and know what I need to do. Just dont know how to properly structure the query and would prefer to not create 3 tables.
Record Types.
Invoice = 1 Credit = 5 Payment = 7
Invoice_Number, Record_Type, Dollar figure
Outstanding_Balance = Invoice(1) -(Payment(7)-(Credit))
Invoice_number Record_type Gen_Numeric_3
Basically I need to take the record_Type 1 and subtract the total of record type 7's from the below.
Invoice_Num Rec_Type Dollar_Amt
00820437 1 536.7700000000
00820437 7 469.6200000000
00820437 7 67.1500000000
Any advice would be great. messer
You can do this with aggregation and case statements:
SELECT invoice_num,
SUM(CASE WHEN rec_type = 1 THEN dollar_amt ELSE 0 END) - (SUM(CASE WHEN rec_type=7 THEN dollar_amt ELSE 0 END) - SUM(CASE WHEN rec_type=5 THEN dollar_amt ELSE 0 END)) as outstanding_balance
FROM yourtable
GROUP BY invoice_num

Grouping totals by date ranges

I have to get totals from a table using different criteria, which I do like this:
SELECT DISTINCT
SUM(CASE WHEN MYCONDITION1 THEN 1 ELSE 0 END) AS TOTAL1,
SUM(CASE WHEN MYCONDITION2 THEN 1 ELSE 0 END) AS TOTAL2
FROM TABLE1, TABLE2
WHERE COMMON_CONDITION1 AND COMMON_CONDITION2
AND BETWEEN DATE1 AND DATE2;
This works fine and I get the intended result.
Now, I have to repeat this for every week for the last 12 months, excluding holidays period. So, I generate a set of date ranges which will be used in the queries. So, I repeat the above sql statement for all the date ranges, which is a lengthy process.
I have to get the totals for every week. For example from 26-Sep-2010 to 02-Oct-2010, 19-Sep-2010 to 25-Sep-2010, 12-Sep-2010 to 18-Sep-2010, etc.. How should I put those ranges in the query for grouping and in the select list, as I don't have them in a table.
How can I do that in a single shot and get all totals for each date range. Please help me with sql.
Thank you.
You could create a table that contains the date ranges. You can join on the new table; you'll have to replace distinct with group by. For example:
SELECT TABLE3.DATE1
, TABLE3.DATE2
, SUM(CASE WHEN MYCONDITION1 THEN 1 ELSE 0 END) AS TOTAL1
, SUM(CASE WHEN MYCONDITION2 THEN 1 ELSE 0 END) AS TOTAL2
FROM TABLE1, TABLE2, TABLE3
WHERE COMMON_CONDITION1
AND COMMON_CONDITION2
AND DATE_COLUMN BETWEEN TABLE3.DATE1 AND TABLE3.DATE2
GROUP BY
TABLE3.DATE1
, TABLE3.DATE2