How to split columns based on field title - sql

I am working with a single warehouse table with columns like "2015 Fee", "2015 Revenue", "2016 Fee", "2016 Revenue", etc. I need to split these out into "Revenue", "Fee", and "Billed Year" in order to do some analysis. Many of the records have fee and revenue in multiple years.
The CASE statement I tried only pulls in the first year, but I need it to pull in all years.
Here's my case statements:
(CASE when 2015_revenue IS NOT NULL then 2015_revenue
when 2016_revenue_$ IS NOT NULL then 2016_revenue
END) as revenue,
(CASE when 2015_fee IS NOT NULL then 2015_fee
when 2016_fee IS NOT NULL then 2016_fee
END) as fee,
(CASE when 2015_revenue IS NOT NULL then '2015'
when 2015_fee IS NOT NULL then '2015'
when 2016_revenue IS NOT NULL then '2016'
when 2016_fee IS NOT NULL then '2016'
end) as bill_year
Any ideas?

It's not a CASE statement, it's creating a temp table with UNIONs and joining to that:
SELECT p1.[bunch of fields from table]
amts.fee
amts.revenue
amts.bill_year
FROM table p1
JOIN (SELECT id, 2015_revenue as revenue, 2015_fee as fee, '2015' as bill_year FROM table
UNION
SELECT id, 2016_revenue as revenue, 2016_fee as fee, '2016' as bill_year FROM table
U) amts on amts.id = p1.id;

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)

Count sequence selected columns

I have query below, I want sequence result like the value of 'feb' will sum by jan and feb, value of 'mar' will sum by jan, feb and mar,... . Is there any way to get the result like that?
select A.location as location
, count(Case When SUBSTRING(A.base_date,5,2)='01' Then A.customer_no else null end) as "jan"
, count(Case When SUBSTRING(A.base_date,5,2)='02' Then A.customer_no else null end) as "feb"
....
, count(Case When SUBSTRING(A.base_date,5,2)='12' Then A.customer_no else null end) as "dec"
from table_income A group by A.location;
SQL is a much more effective language when you think in rows rather than columns (normalisation).
For example, having one row per month is much simpler...
SELECT
location,
SUBSTRING(base_date,5,2) AS base_month,
SUM(COUNT(customer_no))
OVER (
PARTITION BY location
ORDER BY SUBSTRING(base_date,5,2)
)
AS count_cust
FROM
table_income
GROUP BY
location,
SUBSTRING(base_date,5,2)
Side notes:
If your base_date is a string, it shouldn't be, use data-types relevant to the data
If your base_date is a date or timestamp, you should really use date/timestamp functions, such as EXTRACT(month FROM base_date).
You probably should also account for different years...
SELECT
location,
DATE_TRUNC('month', base_date) AS base_month,
SUM(COUNT(customer_no))
OVER (
PARTITION BY location, DATE_TRUNC('year', base_date)
ORDER BY DATE_TRUNC('month', base_date)
)
AS count_cust
FROM
table_income
GROUP BY
location,
DATE_TRUNC('month', base_date)
Try this :
SELECT A.location as location
, count(Case When SUBSTRING(A.base_date,5,2) in ('01') Then A.customer_no else null end) as "jan"
, count(Case When SUBSTRING(A.base_date,5,2) in ('01','02') Then A.customer_no else null end) as "feb"
....
, count(Case When SUBSTRING(A.base_date,5,2) in ('01','02',...'12') Then A.customer_no else null end) as "dec"
from table_income A group by A.location;

Oracle monthly totals and grand total column and row

I'm trying to generate a report using Oracle which looks like this:
I got the following tables:
REGION (IDRegion, Region_Name)
SALES (IDSale, Sale_Date, Amount, IDSaleRegion)
Both tables are populated.
I cannot figure out how can I create that report by extracting each sum for the first 3 months and calculate the totals.
I've only made this script but it's not so useful:
SELECT Region_Name as Region,
COALESCE(NULL, NULL) AS "January",
COALESCE(NULL, NULL)AS"February",
COALESCE(NULL, NULL)AS"March",
COALESCE(NULL, NULL)AS"GrandTotal"
FROM REGION r INNER JOIN SALES s ON r.IDRegion=s.IDSaleRegion
GROUP BY Region_Name;
EDIT: Problem solved except the TOTAL (below Region) which calculates the totals from each Month. Any ideas how to add this row?
You can use Conditional Aggregation
select case grouping(Region_Name) when 1 then 'TOTAL' else Region_Name as "Region",
sum(case when extract(month from Sale_Date) = 1 then Amount else 0 end) AS "January",
sum(case when extract(month from Sale_Date) = 2 then Amount else 0 end) AS "February",
sum(case when extract(month from Sale_Date) = 3 then Amount else 0 end) AS "March",
sum(Amount) AS"GrandTotal"
From yourtable
Where extract(month from Sale_Date) <= 3
Group by Rollup (Region_Name);
try something like this:
SELECT Region_Name as Region,
sum(decode(extract(month from Sale_Date), 1, amount)) AS "January",
sum(decode(extract(month from Sale_Date), 2, amount)) AS"February",
sum(decode(extract(month from Sale_Date), 3, amount)) AS"March",
sum(case when extract(month from Sale_Date)<4 then amount end) AS"GrandTotal"
FROM REGION r INNER JOIN SALES s ON r.IDRegion=s.IDSaleRegion
GROUP BY Region_Name;

How to get records according to column data

I have a table in sql whose name is Trans which contain 4 columns
CustomerID int
TransDate datetime
TransType char(1)
Amount float
CustomerID can contain duplicate ID's but record contain different TransDate or TransType or Amount. TransType contain 'c' for credit and 'd' for debit.
I want to select CustomerId, year, CreditAmount and DebitAmount where CreditAmount is amount where TransType is 'c' and DebitAmount is amount where TransType is 'd'. Year is calculated from TransDate which contain date and time.
I think this is what you are looking for:
select customerid,
datepart(yyyy, transdate) as yr,
sum(case when transtype = 'c' then amount else 0 end) as creditamount,
sum(case when transtype = 'd' then amount else 0 end) as debitamount
from trans
group by customerid,
datepart(yyyy, transdate)
This does assume you want the total credits, for each year, and total debits, for each year, for each customer.
I want to select CustomerId, year, CreditAmount and DebitAmount where
CreditAmount is amount where TransType is 'c' and DreditAmount is
amount where TransType is 'd'. Year is calculated from TransDate which
contain date and time.
I am not sure that I understand you correctly, but you can check:
SELECT
CustomerId
,[Year] = YEAR(TransDate)
,[CreditAmount] = Amount
,[DebitAmount] = (SELECT Amount
FROM Trans t1
WHERE t1.CustomerId = t.CustomerId
AND t1.TransDate = t.TransDate
AND t1.TransType = 'd')
FROM Trans t
WHERE t.TransType = 'c';
I assumed that CustomerId/TranDate/TransType are unique.

Using case to create multiple columns of data

I am trying to create a query in MS SQL 2005 that will return data for 4 date ranges as separate columns in my results set.
Right now my query looks like the query below. It works fine, however I want to add the additional columns for each date range since it currently supports one date range when.
This would then return a total1,total2, total3 and total 4 column instead of a single total column like the current query below. Each total would represent the 4 date ranges:
I am fairly sure this can be accomplished using case statements, but am not 100%.
Any help would be certainly appreciated.
SELECT
vendor,location,
sum(ExtPrice) as total
FROM [database].[dbo].[saledata]
where processdate between '2010-11-03' and '2010-12-14'
and location <>''
and vendor <> ''
group by vendor,location with rollup
I usually do it like this:
SELECT
vendor,location,
sum(CASE WHEN processdate BETWEEN #date1start AND #date1end THEN xtPrice ELSE 0 END) as total,
sum(CASE WHEN processdate BETWEEN #date2start AND #date2end THEN xtPrice ELSE 0 END) as total2,
sum(CASE WHEN processdate BETWEEN #date3start AND #date3end THEN xtPrice ELSE 0 END) as total3,
sum(CASE WHEN processdate BETWEEN #date4start AND #date4end THEN xtPrice ELSE 0 END) as total4
FROM [database].[dbo].[saledata]
and location <>''
and vendor <> ''
group by vendor,location with rollup
And you can change the WHEN portion to make your desired date ranges.
Use Subqueries, ie
select sd.vendor, sd.location, sd1.total, sd2.total, sd3.total, sd4.total
from (select distinct vendor, location from saledata) AS sd
LEFT JOIN (
SELECT vendor,location, sum(ExtPrice) as total
FROM [database].[dbo].[saledata]
where processdate between 'startdate1' and 'enddate1'
and location <>''
and vendor <> ''
group by vendor,location with rollup) sd1 on sd1.vendor=sd.vendor and sd1.location=sd.location
LEFT JOIN (
SELECT vendor,location, sum(ExtPrice) as total
FROM [database].[dbo].[saledata]
where processdate between 'startdate2' and 'enddate2'
and location <>''
and vendor <> ''
group by vendor,location with rollup) sd2 on sd2.vendor=sd.vendor and sd2.location=sd.location
LEFT JOIN (
SELECT vendor,location, sum(ExtPrice) as total
FROM [database].[dbo].[saledata]
where processdate between 'startdate3' and 'enddate3'
and location <>''
and vendor <> ''
group by vendor,location with rollup) sd3 on sd3.vendor=sd.vendor and sd3.location=sd.location
LEFT JOIN (
SELECT vendor,location, sum(ExtPrice) as total
FROM [database].[dbo].[saledata]
where processdate between 'startdate4' and 'enddate4'
and location <>''
and vendor <> ''
group by vendor,location with rollup) sd4 on sd4.vendor=sd.vendor and sd4.location=sd.location