Multiple Choice and Hidden Reports - sql

I have specified the Values in the Which Report Parameter
Label Value
Occupancy Occupancy
Pitch Nights Sold PitchNightsSold
Capacity Capacity
Pitch Nights Sold And Capacity PitchNightsSoldAndCapacity
Pitch Nights Sold And Occupancy PitchNightsSoldAndOccupancy
Pitch Nights Sold Capacity And Occupancy PitchNightsSoldCapacityAndOccupancy
Main Dataset:
SELECT
OccupancyDetail.CalendarYear,
OccupancyDetail.CalendarMonth,
SUM(OccupancyDetail.No_of_Nights) AS No_of_Nights,
SUM(OccupancyDetail.Capacity) AS Capacity
FROM
OccupancyDetail INNER JOIN
Site ON OccupancyDetail.Site_Skey = Site.Site_Skey
WHERE (OccupancyDetail.ReferenceDate = convert(Date,getdate()))
AND CASE WHEN #Time = 'YEAR' THEN CAST(CalendarYear as varchar(4)) else CalendarMonth + ' ' + CAST(CalendarYear as varchar(4)) end in (#Dates)
AND ((#ReportingLevel = 'BDM' AND Site.BDM in(#BDM_Region_Site))
OR (#ReportingLevel = 'Region' AND Site.Region in (#BDM_Region_Site))
OR (#ReportingLevel = 'SiteName' AND Site.SiteName in (#BDM_Region_Site)))
GROUP BY OccupancyDetail.ReferenceDate,OccupancyDetail.CalendarYear, OccupancyDetail.CalendarMonth
Time Dataset:
select
DateChoice
FROM
(
select distinct
CalendarYear,
1 as MonthNumber,
CAST(CalendarYear as varchar(4)) as DateChoice
from Time
where #Time = 'YEAR'
union all
select Distinct
CalendarYear,
MonthNumber,
CalendarMonth + ' ' + CAST(CalendarYear as varchar(4)) as DateChoice
from Time
where #Time = 'MONTH'
) as QRYDATA
ORDER BY CalendarYear,MonthNumber
Site Dataset:
SELECT DISTINCT BDM AS SiteInfo FROM Site
WHERE #ReportingLevel = 'BDM'
UNION ALL
SELECT DISTINCT Region FROM Site
WHERE #ReportingLevel = 'Region'
UNION ALL
SELECT DISTINCT SiteName FROM Site
WHERE #ReportingLevel = 'SiteName'
On Report Builder 3.0 I have created 6 reports that are hidden unless it is selected in a parameter:
Report Code Visibility string:
=iif(Parameters!WhichReport.Value(0) = "Occupancy", False, True)
But what I want to do is make the Parameter a multiple select parameter so someone can choose two charts instead of 1 or choose all 6 etc but whatever selection is made all other reports need to stay hidden. Can this be done and if so how?
Thanks
Wayne

You can modify the Hidden expression to achieve this:
Turn all the selected reports into a string using Join, then check if the relevant report name is in the string, something like:
=IIf(
InStr(Join(Parameters!WhichReport.Value, ","), "Occupancy Report") > 0
, False
, True
)
Or, for a different item:
=IIf(
InStr(Join(Parameters!WhichReport.Value, ","), "Capacity Report") > 0
, False
, True
)
Edit after comment:
I guess you're getting mismatches as values like PitchNightsSold and PitchNightsSoldAndCapacity will confuse the expression as written.
I would use a Dataset similar to the following to control item visibility:
Label Value
----- -----
Occupancy Chart1
Pitch Nights Sold Chart2
Capacity Chart3
Pitch Nights Sold And Capacity Chart4
Pitch Nights Sold And Occupancy Chart5
Pitch Nights Sold Capacity And Occupancy Chart6
Then expressions like:
=IIf(
InStr(Join(Parameters!WhichReport.Value, ","), "Chart1") > 0
, False
, True
)
Will only ever apply to one item.
Since these are your own internal constant values, you can call them whatever you want; just make them distinct and unambiguous. The label will remain unchanged so users will be unaffected when running the report.
Edit after comment:
In a comment #glh offers a good solution to similar Value values:
...if you wrap you join in commas and search for them this will remove
the partial finds.
So something like:
=IIf(
InStr("," + Join(Parameters!WhichReport.Value, ",") + ",", ",PitchNightsSold,") > 0
, False
, True
)
Would work very well, too; credit to him for the suggestion.

Related

Compare data in the same table

I have a table that stores monthly data and I would like to create a comparison between the quantity movement within a period.
Here is an example of the table
.
The SQL statement below is meant to return any changes that has happened within a period - any fund/policy partial or total loss as well as partial or total gain. I have been battling with it for a while - any help would be well appreciated.
I currently have 5 sets of unions - (where the policies and funds match and there's a difference in quantities held, where the policies exist in the previous and not in the current and vice versa and where the securities exist in the previous and not in the current and vice versa) but the other unions work save for the last couple (where the securities exist in the previous and not in the current and vice versa). It doesn't seem to return every occurrence.
SELECT distinct pc.[Client]
,pc.Policy
,cast(pc.Qty as decimal) AS CurrQ
,0 AS PrevQ
,cast(pc.Qty as decimal) - 0 AS QtyDiff
,CASE WHEN cast(pc.Qty as decimal) - 0 > 0 THEN 'Bought Units'
WHEN cast(pc.Qty as decimal) - 0 < 0 THEN 'Sold Units'
ELSE 'Unknown'
END AS TransactionType
,convert(varchar,cast(pc.[ValDate] as date),103) AS CurrValDate
,'' AS PrevValDate
FROM table pc
WHERE convert(varchar,cast(pc.[ValDate] as date),103) = convert(varchar,getdate(),103)
AND pc.Policy IN (SELECT policy
FROM table
WHERE convert(varchar(10),[ValDate],103) = convert(varchar(10),getdate()-1,103)
AND pc.[Fund] NOT IN (SELECT PM.[Fund]
FROM table pc
LEFT JOIN table pm ON pc.policy = pm.policy
WHERE convert(varchar,cast(pc.[ValDate] as date),103) = convert(varchar,getdate(),103))
AND convert(varchar,cast(pm.[ValDate] as date),103) = convert(varchar,getdate()-1,103))
As #Larnu rightly mentioned in the comment section, the extra conditions in the query changed the run from a LEFT JOIN to an INNER JOIN. I changed the code to have policy, fund and date in the ON clause:
FROM table pc
LEFT JOIN table pm ON (pc.policy = pm.policy
AND pc.fund = pm.fund
AND pc.[ValDate]-1 = pm.[ValDate])
and got rid of the sub queries.
Thanks again Larnu.

how can i combine 2 tables and including if clause into one column

I am pretty new in using SQL and trying to combine 2 tables within APEX ( interactive grid), based on the salary and rate the information to be taken from table X ( which i managed), but i need within the same SQL statement based on the information from column Type, to bring within column percentage if clauses to create the information.
and also within the same SQL statement to have the total which would be (ratehourspercentage).
but it seems i just cant manager to combine so many codes into one correctly, i have tried different ways based on what i have found examples all over, but it seems it will just not work for some reason.
select
Overtime.ID,
OVERTIME.EMPLOYEE_NUMBER,
OVERTIME.EMPLOYEE_FULL_NAME,
OVERTIME."DATE",
OVERTIME.TYPE,
OVERTIME.HOURS,
EMPLOYEES.RATE,
EMPLOYEES.SALARY,
OVERTIME.PERCENTAGE (CASE
WHEN TYPE = "On Call " THEN "70%"
WHEN TYPE = "On Call PH" THEN "100%"
ELSE "150%"
END),
(Rate*hours*percentage) as total,
OVERTIME.CREATED,
OVERTIME.CREATED_BY
from OVERTIME
LEFT OUTER JOIN EMPLOYEES
ON OVERTIME.EMPLOYEE_NUMBER = EMPLOYEES.EMPLOYEE_NUMBER
group by Employee_Number
select
Overtime.ID,
OVERTIME.EMPLOYEE_NUMBER,
OVERTIME.EMPLOYEE_FULL_NAME,
OVERTIME."DATE",
OVERTIME.TYPE,
OVERTIME.HOURS,
EMPLOYEES.RATE,
EMPLOYEES.SALARY,
OVERTIME.PERCENTAGE,
(Rate*hours*percentage) as total,
OVERTIME.CREATED,
OVERTIME.CREATED_BY
from OVERTIME
LEFT OUTER JOIN EMPLOYEES
ON OVERTIME.EMPLOYEE_NUMBER = EMPLOYEES.EMPLOYEE_NUMBER
WHERE OVERTIME.TYPE LIKE
(CASE
WHEN TYPE = "On Call " THEN "70%"
WHEN TYPE = "On Call PH" THEN "100%"
ELSE "150%"
END);
group by Employee_number
The table for Overtime has the below:
ID Number primary Key
Employee_number vchar2
employee_full_name vchar2
date date
type vchar2
hours
salary number
rate number
percentage vachar2
total number
created timestamp
created_by vchar2
for the Employees table
ID number primary key
Employee_number vchar2
employee_full_name vchar2
salary number
rate number
i need to have the percentage information to reflect within the percentage column which i presume should be with if clause
You could calculate the total within the select statement using an SQL CASE statement.
Not sure that is the correct way to calculate the Total Pay - as you will want to Add the Basic Hourly rate to the % rate, but you can change that.
select
Overtime.ID,
OVERTIME.EMPLOYEE_NUMBER,
OVERTIME.EMPLOYEE_FULL_NAME,
OVERTIME."DATE",
OVERTIME.TYPE,
OVERTIME.HOURS,
EMPLOYEES.RATE,
EMPLOYEES.SALARY
,[Percentage] = CASE WHEN [Type] ='On Call ' THEN '70%'
WHEN [Type] = 'On Call PH' THEN '100%'
ELSE '150%'
END
,Total = CASE WHEN [Type] = 'On Call ' THEN (EMPLOYEES.RATE * OVERTIME.HOURS * 0.7)
WHEN [TYPE] = 'On Call PH THEN' THEN (EMPLOYEES.RATE * OVERTIME.HOURS)
ELSE (EMPLOYEES.RATE * OVERTIME.HOURS * 1.5)
END
,OVERTIME.CREATED
,OVERTIME.CREATED_BY
from OVERTIME LEFT OUTER JOIN EMPLOYEES ON OVERTIME.EMPLOYEE_NUMBER = EMPLOYEES.EMPLOYEE_NUMBER
group by Employee_Number

Qlik Sense, Counting distinct with a sum

I am trying to create an expression in qlik sense to get the count the distinct number of ID's where each prod is added up and is greater than 0.
Qlik sense expression so far, but wrong:
sum(aggr(count (DISTINCT ID), PROD1 + PROD2 + PROD3 ))
I'm not too sure how to add to the expression where to add >0 and the year month.
Working sql:
select count(distinct ID) as Number
from tb1 x
where (x.Prod1 + x.Prod2 + x.Prod3)> 0
x.Year = '2016/05'
Any help would be great,
Thanks.
The easiest way is with an if statement, your code
select count(distinct ID) as Number
from tb1 x
where (x.Prod1 + x.Prod2 + x.Prod3)> 0
x.Year = '2016/05'
becomes
count (DISTINCT, if((PROD1 + PROD2 + PROD3)>0,ID)))
If you have a date field in your database, you'll need to create a YearMonth field from your date (Date(mydate, 'YYYYMM') as YearMonth) in the data model script and then put this in your expression:
count({<Prod1={'>0'}, Prod2={'>0'}, Prod3={'>0'}, YearMonth={'201605'}>}[distinct ID])
If your field Year in the database is already a yearmonth field, you can do this (but I recommend the first method):
count({<Prod1={'>0'}, Prod2={'>0'}, Prod3={'>0'}, Year={'2016/05'}>}[distinct ID])
You should read this help section from the Qlik site, it's about set analysis
in your script add the calc field:
rangesum(Prod1,Prod2,Prod3) as Prod_Total
"rangesum" also converts null to 0! if Prod1,Prod2 or Prod3 is null you will get 0 as a total.
In the chart use this calc:
count({<Prod_Total={'>0'}>} Distinct ID)

Where Clause using another Dimension Value

I'm trying to create a Calculated Member in my cube with where clause but couldn't figure how to achieve the proper result.
I created a calculated member "Outlook" using the below code to display only Forecast values.
CREATE MEMBER CURRENTCUBE.[Measures].[Outlook]
AS SUM(([Source Profile].[Source Profile Hierarchy].CurrentMember,
[Source Profile].[Profile Level01].&[Outlook]),
[Measures].[USD Amount]),
FORMAT_STRING = "#,##0;(#,##0)",
VISIBLE = 1 , DISPLAY_FOLDER = 'USD' , ASSOCIATED_MEASURE_GROUP = 'CARS';
Cube Result
Now I would like to filter the results dynamically based on another hidden dimension "Current_Month". This dimension always has current financial period value and it's corresponding outlook profile
Year_Month Outlook_Profile
2015010 10 + 2
Expected result should be "Outlook" measure showing value based on Current_Month dimension, which is '10 + 2' and rest of them should be 0
Expected result
Just to explain the requirement in SQL terms, I would like to achieve the below in MDX
Where Fact.Source_Profile=Dimension.Source_Profile
instead of
Where Fact.Source_Profile='10 + 2'
I'm not sure how to achieve this in Where Clause or by another means. I could see examples of hard coding values, like year.&[2015] but haven't seen one using dynamic values.
I found a solution myself and thought of sharing the same. Used StrToMember function to pass hidden dimension's member as a variable here.
CREATE MEMBER CURRENTCUBE.[Measures].[Outlook]
AS (
Sum
(
(
[Source Profile].[Source Profile Hierarchy].CurrentMember,
strtomember("[Source Profile].[Source Name].&[" + [Outlook Profile].[Outlook Profile].&[1].Member_Caption + "]")
)
,[Measures].[USD Amount]
)
),
FORMAT_STRING = "#,##0;(#,##0)",
VISIBLE = 1 , DISPLAY_FOLDER = 'USD' , ASSOCIATED_MEASURE_GROUP = 'CARS' ;

SQL - 2 table values to be grouped by third unconnected value

I want to create a graph that pulls data from 2 user questions generated from within an SQL database.
The issue is that the user questions are stored in the same table, as are the answers. The only connection is that the question string includes a year value, which I extract using the LEFT command so that I output a column called 'YEAR' with a list of integer values running from 2013 to 2038 (25 year period).
I then want to pull the corresponding answers ('forecast' and 'actual') from each 'YEAR' so that I can plot a graph with a couple of values from each year (sorry if this isn't making any sense). The graph should show a forecast line covering the 25 year period with a second line (or column) showing the actual value as it gets populated over the years. I'll then be able to visualise if our actual value is close to our original forecast figures (long term goal!)
CODE BELOW
SELECT CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INTEGER) AS YEAR,
-- first select takes left 4 characters of question and outputs value as string then coverts value to whole number.
CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%forecast' THEN F_TASK_ANS.TA_ANS_ANSWER END) AS NUMERIC(9,2)) AS 'FORECAST',
CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%actual' THEN ISNULL(F_TASK_ANS.TA_ANS_ANSWER,0) END) AS NUMERIC(9,2)) AS 'ACTUAL'
-- actual value will be null until filled in each year therefore ISNULL added to replace null with 0.00.
FROM F_TASK_ANS INNER JOIN F_TASKS ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
-- The two numbers above refer to separate PPM questions that the user enters a value into
I tried GROUP BY 'YEAR' but I get an
Error: Each GROUP BY expression must contain at least one column that
is not an outer reference - which I assume is because I haven't linked
the 2 tables in any way...
Should I be adding a UNION so the tables are joined?
What I want to see is something like the following output (which I'll graph up later)
YEAR FORECAST ACTUAL
2013 135000 127331
2014 143000 145102
2015 149000 0
2016 158000 0
2017 161000 0
2018... etc
Any help or guidance would be hugely appreciated.
Thanks
Although the syntax is pretty hairy, this seems like a fairly simple query. You are in fact linking your two tables (with the JOIN statement) and you don't need a UNION.
Try something like this (using a common table expression, or CTE, to make the grouping clearer, and changing the syntax for slightly greater clarity):
WITH data
AS (
SELECT YEAR = CAST((LEFT(A.TA_ANS_QUESTION,4)) AS INTEGER)
, FORECAST = CASE WHEN A.TA_ANS_QUESTION LIKE '%forecast'
THEN CONVERT(NUMERIC(9,2), A.TA_ANS_ANSWER)
ELSE CONVERT(NUMERIC(9,2), 0)
END
, ACTUAL = CASE WHEN A.TA_ANS_QUESTION LIKE '%actual'
THEN CONVERT(NUMERIC(9,2), ISNULL(A.TA_ANS_ANSWER,0) )
ELSE CONVERT(NUMERIC(9,2), 0)
END
FROM F_TASK_ANS A
INNER JOIN F_TASKS T
ON A.TA_ANS_FKEY_TA_SEQ = T.TA_SEQ
-- It sounded like you wanted to include the ones where the answer was null. If
-- that's wrong, get rid of the test for NULL.
WHERE (A.TA_ANS_ANSWER <> '' OR A.TA_ANS_ANSWER IS NULL)
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
)
SELECT YEAR
, FORECAST = SUM(data.Forecast)
, ACTUAL = SUM(data.Actual)
FROM data
GROUP BY YEAR
ORDER BY YEAR
Try something like this ...
SELECT CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INT) AS [YEAR]
,SUM(CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%forecast'
THEN F_TASK_ANS.TA_ANS_ANSWER ELSE 0 END) AS NUMERIC(9,2))) AS [FORECAST]
,SUM(CAST((CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%actual'
THEN F_TASK_ANS.TA_ANS_ANSWER ELSE 0 END) AS NUMERIC(9,2))) AS [ACTUAL]
FROM F_TASK_ANS INNER JOIN F_TASKS
ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND (TA_TASK_ID LIKE '%6051' OR TA_TASK_ID LIKE '%6052')
GROUP BY CAST((LEFT(F_TASK_ANS.TA_ANS_QUESTION,4)) AS INT)