SSAS MDX Calculated Measure - Grand Total not updating - ssas

Below in the snippet of Geography Hierarchy:
PFB the calculated measure query:
CREATE MEMBER CURRENTCUBE.[Measures].[Metric - vs PY %]
AS
IIf([Geography].[Geography Hierarchy].LEVEL.ORDINAL <> 5,
sum(existing [Geography].[Geography Hierarchy].[1 Country].members
, case when isempty(([Metric Attributes].[Metric name].&[64724],[Measures].[Metric Value]))
or isempty(([Metric Attributes].[Metric name].&[64724],[Measures].[Prev Period Metric Value]))
or isempty(([Metric Attributes].[Metric name].&[64150],[Measures].[Metric Value]))
then null
else
(([Metric Attributes].[Metric name].&[64724],[Measures].[Metric Value])
/ ([Metric Attributes].[Metric name].&[64724],[Measures].[Prev Period Metric Value])
- 1)
* ([Metric Attributes].[Metric name].&[64150],[Measures].[Metric Value])
end
)
/
sum(existing [Geography].[Geography Hierarchy].[1 Country].members
, case when isempty(([Metric Attributes].[Metric name].&[64724],[Measures].[Metric Value]))
or isempty(([Metric Attributes].[Metric name].&[64724],[Measures].[Prev Period Metric Value]))
or isempty(([Metric Attributes].[Metric name].&[64150],[Measures].[Metric Value]))
then null
else
([Metric Attributes].[Metric name].&[64150],[Measures].[Metric Value])
end
)
, case when isempty([Measures].[Base_Metric])
or isempty(([Metric Attributes].[Metric name].&[64724],[Measures].[Prev Period Metric Value]))
then null
else
DIVIDE([Measures].[Base_Metric]
, ([Metric Attributes].[Metric name].&[64724],[Measures].[Prev Period Metric Value]))-1
end
)

Related

UNION ALL IS NOT WORKING WITH GROUP BY IN SQL

I have to create a query that shows whether the employees has taken what kind of leave on time card or if they have taken any leave "Vacation".
The output should look like:
SELECT person_number,
Sum(
CASE
WHEN element = 'Overtime' THEN measure
END) AS overtime_measure_hours,
Sum(
CASE
WHEN elements LIKE 'Regular Pay' THEN measure
END) AS regular_measure_hours,
Sum(
CASE
WHEN elements IN ( 'Double_Time' ) THEN measure
END) AS Other_amount,
Max(
CASE
WHEN elements IN ( 'Double_Time' ) THEN 'Double'
END) AS Other_code
(
SELECT papf.person_number,
atrb.attribute_category element,
atrb.measure measure_hours,
rec.start_date,
rec.end_date
FROM per_all_people_f papf,
hwm_tm_rec rec,
fusion.hwm_tm_rep_atrbs atrb,
fusion.hwm_tm_rep_atrb_usages ausage,
hwm_tm_statuses status
WHERE 1=1
AND atrb.tm_rep_atrb_id = ausage.tm_rep_atrb_id
AND ausage.usages_source_id = rec.tm_rec_id
AND ausage.usages_source_version = rec.tm_rec_version
AND status.tm_bldg_blk_id = rec.tm_rec_id
AND status.tm_bldg_blk_version = rec.tm_rec_version
AND rec.tm_rec_type IN ( 'RANGE',
'MEASURE' )
AND papf.person_number = '101928'
AND trunc (status.date_to) = to_date ('31/12/4712', 'DD/MM/YYYY')
--and atrb.attribute_category in( 'Overtime','Regular Pay', 'Double_Time')
AND trunc (sh21.start_time) BETWEEN trunc(:P_From_Date) AND trunc(:P_To_Date) )
GROUP BY person_number
UNION ALL
SELECT person_number,
sum(
CASE
WHEN element = 'Overtime' THEN measure
END) AS overtime_measure_hours,
sum(
CASE
WHEN elements LIKE 'Regular Pay' THEN measure
END) AS regular_measure_hours,
sum(
CASE
WHEN absence_name IN ( 'Vacation' ) THEN abs_duration
END) AS Other_amount,
max(
CASE
WHEN absence_name IN ( 'Vacation' ) THEN absence_name
END) AS Other_code
(
SELECT papf.person_number,
atrb.attribute_category element,
atrb.measure measure_hours,
rec.start_date,
rec.end_date,
abs.NAME absence_name,
abs.duration abs_duration
FROM per_all_people_f papf,
hwm_tm_rec rec,
fusion.hwm_tm_rep_atrbs atrb,
fusion.hwm_tm_rep_atrb_usages ausage,
hwm_tm_statuses status,
anc_absence_types_vl abs
WHERE 1=1
AND atrb.tm_rep_atrb_id = ausage.tm_rep_atrb_id
AND ausage.usages_source_id = rec.tm_rec_id
AND ausage.usages_source_version = rec.tm_rec_version
AND status.tm_bldg_blk_id = rec.tm_rec_id
AND status.tm_bldg_blk_version = rec.tm_rec_version
AND rec.tm_rec_type IN ( 'RANGE',
'MEASURE' )
AND papf.person_number = '101928'
AND trunc (status.date_to) = to_date ('31/12/4712', 'DD/MM/YYYY')
--and atrb.attribute_category in( 'Overtime','Regular Pay', 'Double_Time')
AND trunc (sh21.start_time) BETWEEN trunc(:P_From_Date) AND trunc(:P_To_Date)
AND abs.absence_type_id = atrb.absence_type_id )
GROUP BY person_number
Although these queries are working separately it is not working with group by on each subquery.
If I merge the two queries, the issue I am having is with Other_code & other_amount. These columns have values from two different tables.
How can I solve this?
Output should be returned for the two dates p_from_date- 01-Jan-2021 and p_to_date- 31-Jul-2021 as:
Person_Number Overtime_measure_hours Regular_Measure_hours Other_code Other_amount
101928 18 15 Double_Time 34
101928 18 15 Vacation 1
i.e. Overtime_measure_hours, Regular_Measure_hours and Other_amount should have the sum of these values.

Best practice when using same query repeatedly

what is the alternative for using same query repeatedly many times. I want to store the query in some place and call it whenever I need it.
I'm computing 4 formulas: MTD sales, MTD previous year sales, MAT sales, MAT previus year sales as separate columns for 5 different products: A,B,C,D,E. along with some static conditions like account details should be provided and direct sales
I'm querying Case statements 4 (for formulas)* 5 (for products) times to define formula with static conditions for all 5 products. i.e. almost 80% of my query is repeated for 4*5 =20 times. Instead of repeating 80% of the query for all 20 times, is there any better way to do it. Kindly note, I don't have to store value of the query as function, instead can I store the repeated portion of the query and call it where ever I need?
Code:
SELECT A1.*,
-- MTD FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=EXTRACT(YEAR FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A)))
THEN SALES ELSE 0 END AS MTD_PRODUCT_D,
---MTD LAST YEAR FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(EXTRACT (MONTH FROM DATE_MONTH)=EXTRACT(MONTH FROM (SELECT MAX(SHOWN_DATE) FROM TABLE_A))
AND
EXTRACT (YEAR FROM DATE_MONTH)=(SELECT EXTRACT(YEAR FROM MAX(SHOWN_DATE))-1 FROM TABLE_A))
THEN SALES ELSE 0 END AS MTD_PY_PRODUCT_D,
----MAT SALES FOR PRODUCT A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-11)
and
trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'))
THEN SALES ELSE 0 END AS MAT_PRODUCT_D,
---MAT LAST YEAR SALES FOR PRODUCTS A,B,C,D
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='A'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_A,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='B'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_B,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='C'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_C,
CASE WHEN
ACCOUNT<> 'Not Provided' AND TYPE<> 'DIRECT' and PRODUCT='D'
AND
(Date_Month between add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-23)
and
add_months(trunc((SELECT MAX(Date_Month) AS MAX_DATE_DIST FROM TABLE_A),'month'),-12))
THEN SALES ELSE 0 END AS MAT_PRODUCT_D
FROM TABLE_A A1
There are several options.
If the underlying data only needs to be created periodically -- say, once per day or once per week, then you can schedule a job and create a table. This is probably the most common solution across different databases for complicated queries.
If the query itself is not particularly complicated or if you need up-to-date data every time, then use a (regular) view. This is the built-in functionality for encapsulating queries.
Another alternative is a materialized view. These are like tables, in that the data does not need to be (explicitly) recalculated. These are like views, in that the data is kept up-to-date. You can learn more about them in the documentation.
Use an analytical function to find the maximum date value:
SELECT A1.*,
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month_trunc = max_date_month
THEN SALES
ELSE 0
END AS MTD_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT <> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month_trunc = max_date_month - INTERVAL '1' YEAR
THEN SALES
ELSE 0
END AS MTD_PY_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month - 11 ) AND max_date_month
THEN SALES
ELSE 0
END AS MAT_PRODUCT_A,
/* B, C, D */
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
AND PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month, -23 ) AND ADD_MONTHS( max_date_month, -12 )
THEN SALES
ELSE 0
END AS MAT_PRODUCT_A
/* B, C, D */
FROM (
SELECT a.*,
TRUNC( date_month, 'MM' ) AS date_month_trunc,
MAX( TRUNC( date_month, 'MM' ) ) OVER () AS max_date_month
FROM TABLE_A a
) A1
You could make it even shorter by moving common elements of the CASE to the sub-query:
SELECT A1.*,
CASE
WHEN PRODUCT='A'
AND date_month_trunc = max_date_month
THEN not_provided_direct_sales
ELSE 0
END AS MTD_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month_trunc = max_date_month - INTERVAL '1' YEAR
THEN not_provided_direct_sales
ELSE 0
END AS MTD_PY_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month - 11 ) AND max_date_month
THEN not_provided_direct_sales
ELSE 0
END AS MAT_PRODUCT_A,
/* B, C, D */
CASE
WHEN PRODUCT='A'
AND date_month BETWEEN ADD_MONTHS( max_date_month, -23 ) AND ADD_MONTHS( max_date_month, -12 )
THEN not_provided_direct_sales
ELSE 0
END AS MAT_PRODUCT_A
/* B, C, D */
FROM (
SELECT a.*,
CASE
WHEN ACCOUNT<> 'Not Provided'
AND TYPE<> 'DIRECT'
THEN SALES
ELSE 0
END AS not_provided_direct_sales,
TRUNC( date_month, 'MM' ) AS date_month_trunc,
MAX( TRUNC( date_month, 'MM' ) ) OVER () AS max_date_month
FROM TABLE_A a
) A1

Combining result rows

I'm trying to get the result below to be displayed group by Article.
Would this be possible?
So that in the end I will only have 2 lines.
The data from TYPE I & W will be combined.
The image to my query as below
image http://tikistudio.sg/F002.jpg
The query as below
SELECT INTSALEID as RECEIPT,
STRSALETYPE as TYPE,
STRORDERCODE as ARTICLE,
max(case when strsaletype='I' then DBLQTYSOLD else null end) as [QTY SOLD],
max(case when strsaletype='I' then CURSELLPRICE1 else null end) as [UNIT PRICE],
max(case when strsaletype='W' then CUROFFERDISCOUNT else null end) as [DISCOUNT],
max(case when strsaletype='I' then CURFOREIGNAMT else null end) as [GROSS AMOUNT]
FROM DAILYSALES
WHERE STRTRADECODE='MM01'
and DTMTRADEDATE='01-01-2015' and INTSALEID='31086'
and STRSALETYPE in ('I','W')
GROUP BY STRORDERCODE,STRSALETYPE,INTSALEID,DBLQTYSOLD,CURSELLPRICE1,
CURFOREIGNAMT,CURDISCOUNT,CUROFFERDISCOUNT
You have to remove some columns in Group By
SELECT
INTSALEID as RECEIPT,
STRORDERCODE as ARTICLE,
MAX(CASE WHEN strsaletype='I' THEN DBLQTYSOLD ELSE NULL END) as [QTY SOLD],
MAX(CASE WHEN strsaletype='I' THEN CURSELLPRICE1 ELSE NULL END) as [UNIT PRICE],
MAX(CASE WHEN strsaletype='W' THEN CUROFFERDISCOUNT ELSE NULL END) as [DISCOUNT],
MAX(CASE WHEN strsaletype='I' THEN CURFOREIGNAMT ELSE NULL END) as [GROSS AMOUNT]
FROM DAILYSALES
WHERE
STRTRADECODE='MM01'
and DTMTRADEDATE='01-01-2015' and INTSALEID='31086'
and STRSALETYPE in ('I','W')
GROUP BY STRORDERCODE,INTSALEID
If you aggregate your data one more time grouping by Receipt, and Article, taking the max value for QTY Sold, Unit Price, Gross Amount and Min Value for Discount.
Select RECEIPT, ARTICLE, MAX([QTY SOLD]) as [QTY SOLD], MAX([UNIT PRICE]) as [UNIT PRICE], MIN([DISCOUNT]) as [DISCOUNT], MAX([GROSS AMOUNT]) as [GROSS AMOUNT]
From
(select INTSALEID as RECEIPT,
STRSALETYPE as TYPE,
STRORDERCODE as ARTICLE,
max(case when strsaletype='I' then DBLQTYSOLD else null end) as [QTY SOLD],
max(case when strsaletype='I' then CURSELLPRICE1 else null end) as [UNIT PRICE],
max(case when strsaletype='W' then CUROFFERDISCOUNT else null end) as [DISCOUNT],
max(case when strsaletype='I' then CURFOREIGNAMT else null end) as [GROSS AMOUNT]
from DAILYSALES
where STRTRADECODE='MM01'
and DTMTRADEDATE='01-01-2015' and INTSALEID='31086'
and STRSALETYPE in ('I','W')
group by STRORDERCODE,STRSALETYPE,INTSALEID,DBLQTYSOLD,CURSELLPRICE1,
CURFOREIGNAMT,CURDISCOUNT,CUROFFERDISCOUNT) x
Group by RECEIPT, ARTICLE

group by week, get first day of week, pivot by weekday

I need to make a query that will show how much of each item/unit combination each customer ordered each week (group by week) while showing the first day the week, and also showing the quantity ordered each day of that week (pivot by weekday). So far i have this, but I'm not sure how to group this by week.
SELECT customer_name, item_code, item_desc, unit, delivery_date, [Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday]
FROM (
SELECT customer_name, item_code , item_desc , unit, delivery_date, DATENAME(dw, delivery_date) AS DayWeek, qty
FROM order_items oi inner join orders on localID = local_order_id
) AS ordersItems
pivot (
SUM(qty) FOR DayWeek IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday])
) AS pvt
The following query groups by customer/item/unit/week# combination. It returns the total number of orders as well as the # of orders broken down by the day of the week. The CASE statement is used along with the SUM function to get the total number of orders for each day of the week
EDIT: Revised query to group by Week Starting Date (instead of week # previously)
SELECT customer_name, item_code, item_desc, unit,
CASE SIGN(7-(DATEPART(dw, action)+2))
WHEN -1 THEN CAST(DATEADD(dd, 7-(DATEPART(dw, action)+2), action) AS DATE)
WHEN 0 THEN CAST(action AS DATE)
WHEN 1 THEN CAST(DATEADD(dd, -(DATEPART(dw, action)+2), action) AS DATE)
END Week_Starting_Friday
SUM(qty) Total_Orders,
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Monday' THEN qty ELSE 0 END
) [Monday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Tuesday' THEN qty ELSE 0 END
) [Tuesday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Wednesday' THEN qty ELSE 0 END
) [Wednesday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Thursday' THEN qty ELSE 0 END
) [Thursday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Friday' THEN qty ELSE 0 END
) [Friday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Saturday' THEN qty ELSE 0 END
) [Saturday],
SUM(
CASE DATENAME(dw, delivery_date) WHEN 'Sunday' THEN qty ELSE 0 END
) [Sunday]
FROM order_items oi inner join orders on localID = local_order_id
GROUP BY customer_name, item_code, item_desc, unit,
CASE SIGN(7-(DATEPART(dw, action)+2))
WHEN -1 THEN CAST(DATEADD(dd, 7-(DATEPART(dw, action)+2), action) AS DATE)
WHEN 0 THEN CAST(action AS DATE)
WHEN 1 THEN CAST(DATEADD(dd, -(DATEPART(dw, action)+2), action) AS DATE)
END
ORDER BY 5, customer_name, item_code, item_desc, unit;
References:
CASE statement on MSDN
DATENAME on MSDN

Unpivot from existing query

I have the following query:
select'Amount' as Amount,
('£'+ CAST(SUM(rc.[Fee Charge] +rc.[Fee Charge VAT] +rc.ExtraCharges+rc.ExtraChargesVAT+rc.OtherCharges+rc.OtherChargesVAT+rc.WaitingCharge+rc.[WaitingCharge VAT])AS nvarchar(50))) AS [CompletedTurnover],
('£'+ CAST(SUM(rin.[Fee Charge] +rin.[Fee Charge VAT] +rin.ExtraCharges+rin.ExtraChargesVAT+rin.OtherCharges+rin.OtherChargesVAT+rin.WaitingCharge+rin.[WaitingCharge VAT])AS nvarchar(50))) AS [In Progress Turnover],
('£'+ CAST(SUM(run.[Fee Charge] +run.[Fee Charge VAT] +run.ExtraCharges+rc.ExtraChargesVAT+run.OtherCharges+run.OtherChargesVAT+run.WaitingCharge+run.[WaitingCharge VAT])AS nvarchar(50))) AS [Unallocated Turnover],
123 as [Credit Note Value]
from tblreservation R
left join tblreservation rc on R.ReservationsID = rc.reservationsid and rc.Completed = 1
left join tblreservation rin on R.reservationsid = rin.reservationsid and rin.InProgress = 1
left join tblreservation run on Run.ReservationsID = r.ReservationsID and run.completed = 0 and run.inprogress = 0
This returns data like so:
CompletedTurnover In progress Turnover Unallocated Turnover Credit Note Value
1202039920 23998858945 9384585845 123
This is as expected. However, I need the following output and I'm struggling a bit using pivots.
Completed Turnover 1202039920
In Progress Turnover 23998858945
Unallocated Turnover 9384585845
Credit Note Value 123
Any help would be greatly appreciated.
This process to convert columns into rows is actually called an UNPIVOT. You can do this a few different ways.
UNPIVOT: function:
;with cte as
(
select'Amount' as Amount,
('£'+ CAST(SUM(rc.[Fee Charge] +rc.[Fee Charge VAT] +rc.ExtraCharges+rc.ExtraChargesVAT+rc.OtherCharges+rc.OtherChargesVAT+rc.WaitingCharge+rc.[WaitingCharge VAT])AS nvarchar(50))) AS [CompletedTurnover],
('£'+ CAST(SUM(rin.[Fee Charge] +rin.[Fee Charge VAT] +rin.ExtraCharges+rin.ExtraChargesVAT+rin.OtherCharges+rin.OtherChargesVAT+rin.WaitingCharge+rin.[WaitingCharge VAT])AS nvarchar(50))) AS [In Progress Turnover],
('£'+ CAST(SUM(run.[Fee Charge] +run.[Fee Charge VAT] +run.ExtraCharges+rc.ExtraChargesVAT+run.OtherCharges+run.OtherChargesVAT+run.WaitingCharge+run.[WaitingCharge VAT])AS nvarchar(50))) AS [Unallocated Turnover],
123 as [Credit Note Value]
from tblreservation R
left join tblreservation rc
on R.ReservationsID = rc.reservationsid
and rc.Completed = 1
left join tblreservation rin
on R.reservationsid = rin.reservationsid
and rin.InProgress = 1
left join tblreservation run
on Run.ReservationsID = r.ReservationsID
and run.completed = 0
and run.inprogress = 0
)
select col, value
from cte
unpivot
(
value
for col in (CompletedTurnover, [In Progress Turnover],
[Unallocated Turnover], [Credit Note Value])
) u;
CROSS APPLY with VALUES:
;with cte as
(
select'Amount' as Amount,
('£'+ CAST(SUM(rc.[Fee Charge] +rc.[Fee Charge VAT] +rc.ExtraCharges+rc.ExtraChargesVAT+rc.OtherCharges+rc.OtherChargesVAT+rc.WaitingCharge+rc.[WaitingCharge VAT])AS nvarchar(50))) AS [CompletedTurnover],
('£'+ CAST(SUM(rin.[Fee Charge] +rin.[Fee Charge VAT] +rin.ExtraCharges+rin.ExtraChargesVAT+rin.OtherCharges+rin.OtherChargesVAT+rin.WaitingCharge+rin.[WaitingCharge VAT])AS nvarchar(50))) AS [In Progress Turnover],
('£'+ CAST(SUM(run.[Fee Charge] +run.[Fee Charge VAT] +run.ExtraCharges+rc.ExtraChargesVAT+run.OtherCharges+run.OtherChargesVAT+run.WaitingCharge+run.[WaitingCharge VAT])AS nvarchar(50))) AS [Unallocated Turnover],
123 as [Credit Note Value]
from tblreservation R
left join tblreservation rc
on R.ReservationsID = rc.reservationsid
and rc.Completed = 1
left join tblreservation rin
on R.reservationsid = rin.reservationsid
and rin.InProgress = 1
left join tblreservation run
on Run.ReservationsID = r.ReservationsID
and run.completed = 0
and run.inprogress = 0
)
select col, value
from cte
cross apply
(
values
('CompletedTurnover', CompletedTurnover),
('In Progress Turnover', [In Progress Turnover]),
('Unallocated Turnover', [Unallocated Turnover]),
('Credit Note Value', [Credit Note Value])
) c (col, value)
You can use a union to get the results you need:
select 'Completed turnover' Description,
( '£'+ CAST(SUM(rc.[Fee Charge] +
rc.[Fee Charge VAT] +
rc.ExtraCharges+
rc.ExtraChargesVAT+
rc.OtherCharges+
rc.OtherChargesVAT+
rc.WaitingCharge+
rc.[WaitingCharge VAT]
)AS nvarchar(50))) value
from ....
union all
select 'In Progress turnover', .....
from ....
union all
select 'Unallocated Turnover', .....
from ....
you probably want to look at using in conjunction with a CTE
Try this,,,,,
select'Amount' as Amount
union all
select
('£'+ CAST(SUM(rc.[Fee Charge] +rc.[Fee Charge VAT] +rc.ExtraCharges+rc.ExtraChargesVAT+rc.OtherCharges+rc.OtherChargesVAT+rc.WaitingCharge+rc.[WaitingCharge VAT])AS nvarchar(50))) AS [CompletedTurnover]
from tblreservation rc where Completed=1
union all
select
('£'+ CAST(SUM(rin.[Fee Charge] +rin.[Fee Charge VAT] +rin.ExtraCharges+rin.ExtraChargesVAT+rin.OtherCharges+rin.OtherChargesVAT+rin.WaitingCharge+rin.[WaitingCharge VAT])AS nvarchar(50))) AS [In Progress Turnover]
from tblreservation rin where InProgress=1
union all
select
('£'+ CAST(SUM(run.[Fee Charge] +run.[Fee Charge VAT] +run.ExtraCharges+rc.ExtraChargesVAT+run.OtherCharges+run.OtherChargesVAT+run.WaitingCharge+run.[WaitingCharge VAT])AS nvarchar(50))) AS [Unallocated Turnover]
from tblreservation run where InProgress=0 and Completed=0
union all
select 123 as [Credit Note Value]
You probably don't need the joins since the aggregate results come from the same table. You could instead use conditional aggregation
SELECT
SUM(CASE WHEN Completed = 1 THEN
[Fee Charge] + [Fee Charge VAT] + ExtraCharges + ExtraChargesVAT +
OtherCharges + OtherChargesVAT + WaitingCharge + [WaitingCharge VAT]
END) AS [Completed Turnover],
SUM(CASE WHEN InProgress = 1 THEN
...
END) AS [In-progress Turnover],
SUM(CASE WHEN Completed = 0 AND InProgress = 0 THEN
...
END) AS [Unallocated Turnover],
123 AS [Credit Note Value]
FROM tblreservation
and then unpivot the results using either of the methods in #bluefeet's answer:
SELECT
Caption,
Value
FROM (
SELECT
SUM(CASE WHEN Completed = 1 THEN
[Fee Charge] + [Fee Charge VAT] + ExtraCharges + ExtraChargesVAT +
OtherCharges + OtherChargesVAT + WaitingCharge + [WaitingCharge VAT]
END) AS [Completed Turnover],
SUM(CASE WHEN InProgress = 1 THEN
...
END) AS [In-progress Turnover],
SUM(CASE WHEN Completed = 0 AND InProgress = 0 THEN
...
END) AS [Unallocated Turnover],
123 AS [Credit Note Value]
FROM tblreservation
) AS s
UNPIVOT (
Value FOR Caption IN (
[Completed Turnover], [In-progress Turnover],
[Unallocated Turnover], [Credit Note Value]
)
) AS u
;
On the other hand, if InProgress and Completed are always either 1 or 0 and they have consistent values in that they cannot both be 1, you could group the results like this:
SELECT
Completed,
InProgress,
SUM(
[Fee Charge] + [Fee Charge VAT] + ExtraCharges + ExtraChargesVAT +
OtherCharges + OtherChargesVAT + WaitingCharge + [WaitingCharge VAT]
) AS Value
FROM tblreservation
GROUP BY
Completed,
InProgress
The next step would be to turn the combinations of Completed and InProgress into proper captions. One method is to use CASE:
SELECT
CASE
WHEN Completed = 1 THEN 'Completed Turnover'
WHEN InProgress = 1 THEN 'In-progress Turnover'
ELSE 'Unallocated Turnover'
END AS Caption
SUM(
[Fee Charge] + [Fee Charge VAT] + ExtraCharges + ExtraChargesVAT +
OtherCharges + OtherChargesVAT + WaitingCharge + [WaitingCharge VAT]
) AS Value
FROM tblreservation
GROUP BY
Completed,
InProgress
And then you would just add the constant Credit Note Value with a UNION ALL:
SELECT
CASE
WHEN Completed = 1 THEN 'Completed Turnover'
WHEN InProgress = 1 THEN 'In-progress Turnover'
ELSE 'Unallocated Turnover'
END AS Caption
SUM(
[Fee Charge] + [Fee Charge VAT] + ExtraCharges + ExtraChargesVAT +
OtherCharges + OtherChargesVAT + WaitingCharge + [WaitingCharge VAT]
) AS Value
FROM tblreservation
GROUP BY
Completed,
InProgress
UNION ALL
SELECT
'Credit Note Value',
123
;