I'm playing around with MDX in the Adventure Works. I trying different things to just practice (so I know there's probably a better way to use the date hierachy to achieve this, but I'm trying it with the Name of Month as opposed to the specific month and year names (if that makes sense). What I'm trying to do is use a case statement that would lag for 2 of my sets, but no lag for the other 2. In other words, I want it to return the 2010 values for my Q1 (July,Aug,Sept) and Q2 (Oct, Nov, Dec) sets, but 2011 values for the Q3(Jan,Feb,Mar) and Q4 sets (Apr, May, June). Here's what I have, but the case statement just gives lag 1 for all. So I'm understanding how it's working, but can't seem to wrap my head around how to return the different values for each set as stated above.
WITH
SET [Q1 Combined] AS {
[Date].[Month of Year].&[7],
[Date].[Month of Year].&[8],
[Date].[Month of Year].&[9] }
SET [Q2 Combined] AS {
[Date].[Month of Year].&[10],
[Date].[Month of Year].&[11],
[Date].[Month of Year].&[12] }
SET [Q3 Combined] AS {
[Date].[Month of Year].&[1],
[Date].[Month of Year].&[2],
[Date].[Month of Year].&[3] }
SET [Q4 Combined] AS {
[Date].[Month of Year].&[4],
[Date].[Month of Year].&[5],
[Date].[Month of Year].&[6] }
MEMBER [Date].[Month of Year].[FY Q1 Fix] AS Aggregate([Q1 Combined])
MEMBER [Date].[Month of Year].[FY Q2 Fix] AS Aggregate([Q2 Combined])
MEMBER [Date].[Month of Year].[FY Q3 Fix] AS Aggregate([Q3 Combined])
MEMBER [Date].[Month of Year].[FY Q4 Fix] AS Aggregate([Q4 Combined])
SELECT
[Measures].[Internet Sales Amount] ON COLUMNS,
{
[Date].[Month of Year].[FY Q1 Fix],
[Date].[Month of Year].[FY Q2 Fix],
[Date].[Month of Year].[FY Q3 Fix],
[Date].[Month of Year].[FY Q4 Fix]} ON ROWS
} ON ROWS
FROM [Adventure Works]
WHERE **I WANT TWO DIFFERENT SLICES**
So in other words, I want:
[FY Q1 Fix] and [FY Q2 Fix] to be sliced and show [Date].[2010] measures
[FY Q3 Fix] and [FY Q4 Fix] sliced by and show [Date].[2011] measures
I'd be more inclined to put the logic of the different slices in your WITH clause rather than WHERE clause. So in the following you can see there is one hard-coded year and then I use lag against two of the quarter sets:
WITH
SET [targetYear] AS
[Date].[Fiscal Year].&[2008]
SET [Q1 Combined] AS
{
[Date].[Month of Year].&[7]
,[Date].[Month of Year].&[8]
,[Date].[Month of Year].&[9]
}
*
[targetYear].Item(0)
SET [Q2 Combined] AS
{
[Date].[Month of Year].&[10]
,[Date].[Month of Year].&[11]
,[Date].[Month of Year].&[12]
}
*
[targetYear].Item(0)
SET [Q3 Combined] AS
{
[Date].[Month of Year].&[1]
,[Date].[Month of Year].&[2]
,[Date].[Month of Year].&[3]
}
*
[targetYear].Item(0).Lag(1)
SET [Q4 Combined] AS
{
[Date].[Month of Year].&[4]
,[Date].[Month of Year].&[5]
,[Date].[Month of Year].&[6]
}
*
[targetYear].Item(0).Lag(1)
MEMBER [Date].[Month of Year].[FY Q1 Fix] AS
Aggregate([Q1 Combined])
MEMBER [Date].[Month of Year].[FY Q2 Fix] AS
Aggregate([Q2 Combined])
MEMBER [Date].[Month of Year].[FY Q3 Fix] AS
Aggregate([Q3 Combined])
MEMBER [Date].[Month of Year].[FY Q4 Fix] AS
Aggregate([Q4 Combined])
SELECT
[Measures].[Internet Sales Amount] ON COLUMNS
,{
[Date].[Month of Year].[FY Q1 Fix]
,[Date].[Month of Year].[FY Q2 Fix]
,[Date].[Month of Year].[FY Q3 Fix]
,[Date].[Month of Year].[FY Q4 Fix]
} ON ROWS
FROM [Adventure Works];
Related
First, I'm sure there is a cleaner way to do this, but it's the only way I've been able to make the code combine the DX's into one column. Originally they were in separate columns as 0/1's and I needed them in one column. I tried the PIVOT function, but was not able to figure it out.
The issue is I need the paid amounts to be based on duplicated instances DX's. Which sounds counterintuitive, but for this report it's what I need.
For example. If member A has COPD, ASTHMA, AND DIABETES. The member's paid claims were 40,000 so I need the paid amount for that member to reflect 120,000, etc. and so forth.
The code:
SELECT
DX_FLAG
,Sum( AMT_PAID) AS PHARM_PAID_AMT
,Count(DISTINCT(MEMBER_AMISYS_NBR)) AS MEMBER_COUNT
FROM
(SELECT
st.MEMBER_AMISYS_NBR
,ph.PHARMACY_CLAIM_CK
,ph.AMT_PAID
,FILL.DATE_DATE AS Fill_Date
,Coalesce(CASE WHEN DX_ASTHMA = 'ASTHMA' THEN 'Asthma' END,
CASE WHEN DX_COPD = 'COPD' THEN 'COPD' END,
CASE WHEN DX_DIABETES = 'DIABETES' THEN 'DIABETES' END,
CASE WHEN DX_HEART_FAILURE = 'HEART FAILURE' THEN 'HEART_FAILURE' END,
CASE WHEN DX_HYPERTENSION = 'HYPERTENSION' THEN 'HYPERTENSION' END)
AS DX_FLAG
FROM
STATE_OVERALL_MBRS st
JOIN FT_PHARMACY_CLAIM ph ON st.MEMBER_CURR_CK = ph.PRESCRIBER_MEMBER_CURR_CK AND ph.DELETED_IND = 'N'
JOIN DIM_DATE FILL ON ph.FILL_DATE_DIM_CK = FILL.DATE_DIM_CK
WHERE FILL.DATE_DATE BETWEEN '2021-10-01' AND '2022-09-30'
AND ph.PLAN_DIM_CK =10
AND ph.REVERSAL_IND = 'N'
AND ph.AMT_PAID > 0
) rx
My output looks like this .
DX_FLAG
PHARM_PAID_AMT
MEMBER_COUNT
DIABETES
70,000,000
14,144
COPD
38,266,409
6,641
HEART_FAILURE
10,908,000
2,544
ASTHMA
125,000,000
30,000
HYPERTENSION
52,900
22,325
I have tried adding/removing the Distinct from each select statement and the only one that made a difference was removing distinct from this line, in which case I ended up with far too many member counts (even taking into account the duplicate DX counts).
,Count(DISTINCT(MEMBER_AMISYS_NBR)) AS MEMBER_COUNT
The State_Overall_Mbrs table with DX_Flag looks like this and I needed all the diagnosis to be in one column (with duplicate rows for members depending on how many diagnoses they have):
Member ID Asthma COPD Hypertension Diabetes CHF
55555555 0 1 1 1 0
66666666 1 0 0 1 0
77777777 0 0 1 0 0
Normalize the members table, then join and aggregate; something like this:
SELECT
DX_FLAG
,Sum(AMT_PAID) AS PHARM_PAID_AMT
,Count(DISTINCT(MEMBER_AMISYS_NBR)) AS MEMBER_COUNT
FROM
(SELECT * FROM State_Overall_Members
UNPIVOT (has_dx /* New column to hold the 0 or 1 value */
FOR DX_FLAG IN (Asthma,COPD,Hypertension,Diabetes,CHF)
/* Original column names become the values in new column DX_FLAG */
) nmlz
WHERE has_dx = 1 /* Only unpivot rows with a 1 in original column */
) st
JOIN FT_PHARMACY_CLAIM ph ON st.MEMBER_CURR_CK = ph.PRESCRIBER_MEMBER_CURR_CK AND ph.DELETED_IND = 'N'
JOIN DIM_DATE FILL ON ph.FILL_DATE_DIM_CK = FILL.DATE_DIM_CK
WHERE FILL.DATE_DATE BETWEEN '2021-10-01' AND '2022-09-30'
AND ph.PLAN_DIM_CK =10
AND ph.REVERSAL_IND = 'N'
AND ph.AMT_PAID > 0
GROUP BY DX_FLAG;
Another option to normalize the members table would be to have a subquery for each DX and UNION those, along these lines:
... FROM
(SELECT MEMBER_CURR_CK, MEMBER_AMISYS_NBR, AMT_PAID, 'Asthma' (VARCHAR(16)) AS DX_FLAG
FROM State_Overall_Members
WHERE Asthma = 1
UNION ALL
SELECT MEMBER_CURR_CK, MEMBER_AMISYS_NBR, AMT_PAID, 'COPD' (VARCHAR(16)) AS DX_FLAG
FROM State_Overall_Members
WHERE COPD = 1
UNION ALL
...
) st
JOIN ...
I am quit new at this (sqlite) using sqlite studio.
I have a table with many rows, trying to view dates, objects, purchase price, sold price and the difference.
This is what I get
DATE OBJ BOUGHT SOLD DIFF
2009 OBJ1 235000 NULL NULL
2012 OBJ2 255500 NULL NULL
2021 OBJ3 305400 NULL NULL
2012 OBJ1 NULL 255500 NULL
2021 OBJ2 NULL 309000 NULL
This is what I want
DATE OBJ BOUGHT SOLD DIFF
2009 OBJ1 235000 255500 20500
2012 OBJ2 255500 309000 53500
2021 OBJ3 305400 NULL NULL
Code:
SELECT strftime('%Y', Op_Date) Year, Op_Obj OBJ ifnull(Op_TTBuy, 0) BOUGHT, ifnull(Op_TTSell, 0) SOLD, (Op_TTSell - Op_TTBuy) DIFF
FROM Operations
I tried many ways..
Any help would be appreciated..
You may need to group by year, something along these lines:
SELECT strftime('%Y', Op_Date) Year, max(Op_Ob) OBJ
, sum(ifnull(Op_TTBuy, 0)) BOUGHT
, sum(ifnull(Op_TTSell, 0)) SOLD
, (sum(Op_TTSell) - sum(Op_TTBuy)) DIFF
FROM Operations
group by strftime('%Y', Op_Date)
order by strftime('%Y', Op_Date)
There are 21 rows in the table. 7 are for year 2011, 7 are for 2012 and the remaining 7 are for 2013. I want to get the latest year's 7 rows.
SELECT S1, S2, S1 * S2 AS M
FROM BLGND
WHERE DID = #dID AND
PMID = #pmID AND
yearr IN (SELECT MAX(yearr) AS y FROM BLGND AS BLGND_1)
I successfully bring the latest year's rows with the query above in MS Visual Studio Environment. But When I run the query in an ASP.NET page It brings all 21 records.
In other words yearr IN (SELECT MAX(yearr) AS y FROM BLGND AS BLGND_1) makes no difference.
yearr column's type is int
What could be the problem? OR is there a better query you know?
You could simply write
SELECT S1, S2, S1 * S2 AS M
FROM BLGND
WHERE DID = #dID AND
PMID = #pmID AND
YEAR([fieldWithDate]) = #yearRequested
Where fieldWithDate is assumed to be a smalldatetime or datetime field from which you want to get the year value and #yearRequested is a parameter that you pass to your query from your code.
You could extract the year value using the YEAR(expression) T-SQL function
Of course, if the field to search for the year value is just an integer containing the year values of your rows the query is simpler
SELECT S1, S2, S1 * S2 AS M
FROM BLGND
WHERE DID = #dID AND
PMID = #pmID AND
fieldWithYearValue = #yearRequested
If you don't want to pass the parameter for the year, but just want to retrieve always the set of rows of the last year for a specific user then
SELECT S1, S2, S1 * S2 AS M
FROM BLGND
WHERE DID = #dID AND
PMID = #pmID AND
fieldWithYearValue = (SELECT MAX(fieldWithYearValue) FROM BLGND)
In my SQL database I have a column that contains a fiscal year value. Fiscal Year start from Oct 1st to Sept 30th of the following year. For example the current fiscal year is 2011-2012 or "2011". I need a calculation to pull dates from my database.
I have a column in my table that contains dates (i.e. 05/04/2012), I need a calculation that will pull the dates for the selected fiscal year? So when I need to see the data for the date 02/14/2003, then I would need the fiscal year of 2002.
This all ties into my ASP.NET page, where a user selects which fiscal year they want to view and a gridview appears with the information requested. So, if I choose fiscal year 2010, the data pulled into the gridview should be all records from 10/01/2010 to 09/30/2011. Thanks for the help, I have yet to try anything because I am not sure where to begin (sql newbie).
You can find the fiscal year by adding three months:
year(dateadd(month,3,'2011-09-30'))
So to select all entries in Fiscal year 2011, try:
select *
from YourTable as yt
where year(dateadd(month,3,yt.TransactionDt)) = 2011
I assume you are using SqlParameters to send data to the SQL Server. Then:
int fiscal_year = 2002;
SqlParameter fyStart = new SqlParameter("#FiscalYearStart",
SqlDbType.DateTime);
fyStart.Value = new SqlDateTime(fiscalYear, 10, 01);
SqlParameter fyEnd = new SqlParameter("#FiscalYearEnd",
SqlDbType.DateTime);
fyEnd.Value = new SqlDateTime(fiscalYear+1, 10, 01);
Then you can pass these two params to an Stored Procedure for example, and to query the table with
WHERE date BETWEEN #FiscalYearStart AND #FiscalYearEnd
N.B. FiscalYearEnd should be 10-Oct-YEAR+1, as it will be represented as YYYY-10-01T00:00:00, or will include the whole 30 Sept.
You could query for it:
SELECT *
FROM YourTable
WHERE YourTableDate >= CAST(#FiscalYear AS CHAR(4)) + '-10-01'
AND YourTableDate < CAST(#FiscalYear + 1 AS CHAR(4)) + '-10-01';
or, if you need the flexibility, you could alternatively have a table of date ranges which join to fiscal years. This gives you the ability to have multiple fiscal year definitions for, say, multiple tenants or companies, or allows the definition to change without changing your queries. You could then join to this table as needed to filter your results.
CompanyID FiscalYear StartDate EndDate
1 2010 2010-10-01 2011-09-30
1 2011 2011-10-01 2012-09-30
2 2010 2010-01-01 2011-12-31
2 2011 2011-01-01 2012-12-31
SELECT *
FROM YourTable t
INNER JOIN FiscalYear y
ON y.FiscalYear = t.FiscalYear
WHERE t.YourTableDate >= y.StartDate AND t.YourTableDate < DATEADD(d, 1, y.EndDate);
i have two tables:
table 1:
Expense cost
Posting Date
table 2:
Employee cost
Rvenue
Billing Date
Totalcost = Expense cost + Employee cost
Pofit Revenue - TotalCost
i have to display the report like so. It should show data per month according to year lets say 2011, (i know how to filter by year)
Totalcost | Revenue | Profit
jan
feb
mar
apr
may
jun
jul
aug
sep
oct
nov
dec
I'm having a tough time fugring out the query.
The problem is how can i display the data in report viewer table
Simplest way would be to combine the data to form a single data-table that will act as a data-source for the report.
You can join both tables at database side - for example,
SELECT
t1.Month,
t1.ExpenseCost + t2.EmployeeCost AS TotalCost,
t2.Revenue,
t2.Revenue - t1.ExpenseCost - t2.EmployeeCost AS Profit
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.Year = t2.Year and t1.Month = t2.Month
WHERE
t1.Year = #Year /* parameter to filter for a year */
or you can combine the data at front end either by using data relation or more simply by using LINQ over data tables - for example
var query = from t1 in table1.AsEnumerable()
join t1 in table2.AsEnumerable()
on t1.Field<string>("Month") equals t2.Field<string>("Month")
select new
{
Month = t1.Field<string>("Month"),
TotalCost = t1.Field<Decimal>("ExpenseCost") + t2.Field<Decimal>("EmployeeCost"),
Revenue = t2.Field<Decimal>("Revenue"),
// similarly compute profit
};