I faced with a grouping problem in Chart >>> Pivot table of Apache Superset (version 2023.01.1). I created pivot table chart with all criterias as below Column A: Product list, Column B: Jan, Column C: Feb till Dec.
So in Pivot Table Superset like: Time = Months, Columns = date , Rows = Product list and
Metric=
CASE
WHEN Product_List = 'Product_A' AND to_char(date,'Mon' ) = 'Jan'
THEN (SUM(sales)/(10000*0.01)
WHEN Product_List = 'Product_B' AND to_char(date,'Mon' ) = 'Feb'
THEN (SUM(sales)/(20000*0.01)
END
So the goal is to find the rate of products for each months based on different target sales. For Example
Sales for Jan = 100 units
Target sales for Jan = 1000 units
Rate = 100/1000*0.01= %10 for Jan
Sales for Feb = 150 units
Target sales for Feb = 2000 units
Rate = 150/2000*0.01= %Feb for Feb
Pivot Table:
Product Name
Jan
Product A
%20
Product B
%25
Note: The SQL code above is working in SQL LAB in Apache Superset. However When I apply it to chart>pivot table>metrics. it gives me error as 'must appear in the GROUP BY clause or be used in an aggregate function'
Related
I need to find the price for an item for each financial year end date in a date range. In this case the financial year is e.g. 31 March
The table I have for example:
ItemID
Value
DateFrom
DateTo
1
10
'2019/01/01'
'2021/02/28'
1
11
'2021/03/01'
'2021/05/01'
SQL Fiddle
The SQL would thus result in the above table to be:
ItemID
Value
DateFrom
DateTo
1
10
'2019/01/01'
'2019/03/30'
1
10
'2020/03/31'
'2021/02/28'
1
11
'2020/03/01'
'2021/03/30'
1
11
'2020/03/31'
'2021/05/01'
You can solve it, but a prerequisite is the creation of a table called financial_years and filling it with data. This would be the structure of the table:
financial_years(id, DateFrom, DateTo)
Now that you have this table, you can do something like this:
select ItemID, Value, financial_years.DateFrom, financial_years.DateTo
from items
join financial_years
on (items.DateFrom between financial_years.DateFrom and financial_years.DateTo) or
(items.DateTo between financial_years.DateFrom and financial_years.DateTo)
order by financial_years.DateFrom;
The accepted answer is not correct, as it does not split out different parts of the year which have different values.
You also do not need a Year table, although it can be beneficial. You can generate it on the fly using a VALUES table.
Note also a better way to check the intervals overlap, using AND not OR
WITH Years AS (
SELECT
YearStart = DATEFROMPARTS(v.yr, 3, 31),
YearEnd = DATEFROMPARTS(v.yr + 1, 3, 31)
FROM (VALUES
(2015),(2016),(2017),(2018),(2019),(2020),(2021),(2022),(2023),(2024),(2025),(2026),(2027),(2028),(2029),(2030),(2031),(2032),(2033),(2034),(2035),(2036),(2037),(2038),(2039)
) v(yr)
)
SELECT
i.ItemID,
i.Value,
DateFrom = CASE WHEN i.DateFrom > y.YearStart THEN i.DateFrom ELSE y.YearStart END,
DateTo = CASE WHEN i.DateTo > y.YearEnd THEN y.YearEnd ELSE i.DateTo END
FROM items i
JOIN Years y ON i.DateFrom <= y.YearEnd
AND i.DateTo >= y.YearStart;
I have searched but have been unable to find any other queries like this one. I have a query with month and year parameters and the counts are summed into a matrix. Everything works well for months Jan to Sept incl and year 2018 however when I test it with November or December 2018 and January 2019 I am getting results in the query pane but nothing in the matrix (not even zeros).
The where clause in my query is:
(edited 7/2/18 to show updated YYYY)
WHERE (DATEPART(MM, createdon) = #selectedMonth) AND (DATEPART(YYYY, createdon) = #selectedYear) OR
(DATEPART(MM, sb_provisionalstatuschangedate) = #selectedMonth) AND (DATEPART(YYYY, sb_provisionalstatuschangedate) = #selectedYear) OR
(DATEPART(MM, sb_confirmedstatuschangedate) = #selectedMonth) AND (DATEPART(YYYY, sb_confirmedstatuschangedate) = #selectedYear) OR
(sb_status = 3) AND (statecode = 1) AND (DATEPART(MM, sb_eventdate) = #selectedMonth) AND (DATEPART(YYYY, sb_eventdate) = #selectedYear) OR
(statecode = 2) AND (DATEPART(MM, actualclosedate) = #selectedMonth) AND (DATEPART(YYYY, actualclosedate) = #selectedYear)
ORDER BY sb_eventdate, BookingName
I have set up available values within the #month parameter for months 1 to 12 and within the #year parameter for 2018 to 2022 (inclusive).
An example of one of the expressions (first column):
=Sum(iiF(DatePart("m", Fields!createdon.Value) = Parameters!selectedMonth.Value And DatePart("yyyy", Fields!createdon.Value) = Parameters!selectedYear.Value, 1, 0))
I tested everything for user selection of Jan 2018 and exported the results and counted what the results should be and everything was correct.
As a lot of my testing had been on the Jan 18 data I also tested all the other months in 2018. Everything went well until I got to November and December when I get no results - not even zeros.
This would normally indicate a problem with the data and therefore no results so I ran the query in SQL query pane (inserting a 12 where query shows #Month and 2018 where query shows #year, which I exported and checked - (the top 10 results showing should all be counting in the matrix under 'cancelled'). There are results for all of the columns. If there had been no results I would still have expected to see zeros.
Is anyone able to explain why I am getting nothing for Novemebr, December 18 and also for Jan 19?
Try this: in your where clause "DATEPART(YY" amend this to "DATEPART(YYYY"
on the 4th line of your query you have :
(DATEPART(MM, sb_eventdate) = 2018)
This should be:
(DATEPART(YYYY, sb_eventdate) = 2018)
I have managed to sort out the problem and it was that another instance of the database had been created which has now become the main database and the one that used to be the main database is now for emergency only - obviously does not hold the same data. I was querying one instance on the SQL query pane and another instance in visual studio. I apologise for wasting your time on something that would not have happened if our communications were better.
I have two datasets, one with contracts and one with market prices. The gist of what I am trying to accomplish is to find the average value of a time series that corresponds to a period of time in a cross-sectional data set. Please see below.
Example Dataset 1:
Beginning Ending Price
1/1/2014 5/15/2014 $19.50
3/2/2012 10/9/2015 $20.31
...
1/1/2012 1/8/2012 $19.00
In the example above there are several contracts, the first spanning from January 2014 to May 2014, the second from March 2012 to October 2015. Each one has a single price. The second dataset has weekly market prices.
Example Dataset 2:
Date Price
1/1/2012 $18
1/8/2012 $17.50
....
1/15/2015 $21.00
I would like to find the average "market price" (i.e. the average of the price in dataset 2) between the beginning and ending period for each contract on dataset 1. So, for the third contract from 1/1/2012 to 1/8/2012, from the second dataset the output would be (18+17.50)/2 = 17.75. Then merge this value back to the original dataset.
I work with Stata, but can also work with R or Excel.
Also, if you have a better suggestion for a title I would really appreciate it!
You can cross the contracts cross section data with the time series, which forms every pairwise combination, drop the prices from outside the date range, and calculate the mean like this:
/* Fake Data */
tempfile ts ccs
clear
input str9 d p_daily
"1/1/2012" 18
"1/8/2012" 17.50
"1/15/2015" 21.00
end
gen date = date(d,"MDY")
format date %td
drop d
rename date d
save `ts'
clear
input id str8 bd str9 ed p_contract
1 "1/1/2014" "5/15/2014" 19.50
2 "3/2/2012" "10/9/2015" 20.31
3 "1/1/2012" "1/8/2012" 19.00
end
foreach var of varlist bd ed {
gen date = date(`var',"MDY")
format date %td
drop `var'
rename date `var'
}
save `ccs'
/* Calculate Mean Prices and Merge Contracts Back In */
cross using `ts'
sort id d
keep if d >= bd & d <=ed
collapse (mean) mean_p = p_daily, by(id bd ed p_contract)
merge 1:1 id using `ccs', nogen
sort id
This gets you something like this:
id p_contract bd ed mean_p
1 19.5 01jan2014 15may2014 .
2 20.31 02mar2012 09oct2015 21
3 19 01jan2012 08jan2012 17.75
I have a problem which seems to be very simple to solve but I can't. In my Fact table I have a Timestamp field which is a smalldatetime Type. This fact is linked to a Time dimension via its fulldate_Fk (also SmallDatetime). So What I would like to have is to compare the timestamp with the FullDate_FK from the fact to create a calculation like this:
iif([Dim Time].[Date].CurrentMember.MemberValue <=
[Fact].[Timestamp].CurrentMember.MemberValue
,[measures].[YTD Actuals]
,[measures].[YTD Actuals]+[measures].[YTD Com])
But it is not working at all. All [Dim Time].[Date] seem to be evaluated as < than the Timestamp.
P.S: The Timestamp is the last date when the data have been loaded in the DB (in my case 31/08)
Here the result I got:
MONTH | YTD Actuals | YTD Com | Calculation;
JAN , 10 , 10 , 10;
FEB , 20 , 10 , 20;
MAR , 40 , 20 , 40;
MAY , 60 , 30 , 60;
JUN , 70 , 50 , 70;
JUL , 85 , 50 , 85;
AUG , 120 , 55 , 120;
SEP , 120 , 60 , 120;
OCT , 120 , 70 , 120;
NOV , 120 , 80 , 120;
DEC , 120 , 90 , 120;
From August, I should have the sum of Actuals YTD and Com YTD in the calculation, but I still have the Actuals YTD only?
Extra Info
I'm using PivotTable just by dragging attributes in Excel. Month in rows and measures (the 2 YTD and the new calculated member)
If you build a new calc which is:
[Fact].[Timestamp].CurrentMember.MemberValue
What does it return when you add it to your PivotTable? Null? I suspect the CurrentMember is the All member so MemberValue is null. But let's test that.
Do all rows in the fact table have the same Timestamp or are there many different timestamps?
If your fact table has 10000 rows are you expecting the IIf calc will be evaluated 10000 times (once for each row)? That's not the way MDX works. In your PivotTable that has 12 rows the IIf calc gets evaluated 12 times at the month grain.
If you want the calculation to happen on each of the 10000 rows then write the calculation in SQL and do it in a SQL view before it gets to the cube.
To make the calc work as you intend in the cube consider doing the following. Add a new column in your DimTime SQL table called Today Flag. It should be updated during the ETL to be Y only on the row which is today and should be N on other rows. Then add that column as a new attribute to your Dim Time dimension. You can make it Visible=False. Then go to the Calculations tab and flip to the Script view and replace your current [Measures].[Calculation] calc with this:
Create Member CurrentCube.[Measures].[Calculation] as
[measures].[YTD Actuals];
Scope({Exists([Dim Time].[Month].[Month].Members,[Dim Time].[Today Flag].&[Y]).Item(0).Item(0):null});
[Measures].[Calculation] = [measures].[YTD Actuals]+[measures].[YTD Com];
End Scope;
I'm trying to write a query that would give me the records of all members that have Order dates that exist in 2013 but not in 2014. When I write my query it gives me ALL of the 2013 records which still exist in 2014. I'm trying to get ONLY record that have order dates in 2013 and not in 2014. So it should show records which exist in 2013 and exclude records that do not exist in 2014. Please help as I'm really new to SQL.
Thank you very much.
Below is my query:
SELECT
OMFMC.BILL_MASTER_CUSTOMER_ID,
OMFMC.BILL_FIRST_NAME,
OMFMC.BILL_LAST_NAME,
CMI.NATIONAL_LEVEL2,
MIN(OMFMC.ORDER_DATE),
OMFMC.ORDER_DATE,
FT.PAYMENT_AMOUNT,
SUM(FT.PAYMENT_AMOUNT)as SUM
FROM
CUSTOMER CUSTOMER_IN_TRIBUTE_TO
RIGHT OUTER JOIN ORDER_FND_DETAIL OFD
ON (CUSTOMER_IN_TRIBUTE_TO.MASTER_CUSTOMER_ID=OFD.IN_TRIBUTE_TO_MAST_CUST
and CUSTOMER_IN_TRIBUTE_TO.SUB_CUSTOMER_ID=OFD.IN_TRIBUTE_TO_SUB_CUST)
RIGHT OUTER JOIN ORDER_MBR_FND_MTG_CUS_INFO_VW OMFMC
ON (OMFMC.ORDER_NO=OFD.ORDER_NO
and OMFMC.ORDER_LINE_NO = OFD.ORDER_LINE_NO )
LEFT OUTER JOIN CUS_CURRENT_MEMBERSHIP_INFO CMI
ON (CMI.MASTER_CUSTOMER_ID=OMFMC.BILL_MASTER_CUSTOMER_ID
and CMI.SUB_CUSTOMER_ID=OMFMC.BILL_SUB_CUSTOMER_ID)
LEFT OUTER JOIN FAR_TXN FT
ON (FT.ORDER_NO=OMFMC.ORDER_NO
and FT.ORDER_LINE_NO=OMFMC.ORDER_LINE_NO)
WHERE
OMFMC.ORDER_STATUS_CODE='A'
AND OMFMC.LINE_STATUS_CODE = 'A'
AND OMFMC.ORDER_STATUS_CODE = 'A'
AND OMFMC.LINE_STATUS_CODE = 'A'
AND OMFMC.ORDER_DATE BETWEEN '1/1/2013' and '12/31/2013'
AND OMFMC.ORDER_DATE Not BETWEEN '1/1/2014' and '12/31/2014'
AND OMFMC.BILL_CUSTOMER_CLASS_CODE NOT IN ( 'TEST_MBR','STAFF' )
AND FUND in ('FOSFN' , 'MFUND')
GROUP BY
OMFMC.BILL_MASTER_CUSTOMER_ID,
OMFMC.BILL_FIRST_NAME,
OMFMC.BILL_LAST_NAME,
OMFMC.BILL_LABEL_NAME,
OMFMC.BILL_PRIMARY_EMAIL_ADDRESS,
OMFMC.BILL_ADDRESS_1,
OMFMC.BILL_ADDRESS_2,
OMFMC.BILL_CITY,
OMFMC.BILL_STATE,
OMFMC.BILL_POSTAL_CODE,
CMI.NATIONAL_LEVEL2,
OMFMC.ORDER_DATE,
FT.PAYMENT_AMOUNT
HAVING SUM(FT.PAYMENT_AMOUNT) < 0
Order By BILL_MASTER_CUSTOMER_ID
In the order dates field, there are dates that have 2013, and 2014 dates. I want a my query to look at 2013 and 2014 order dates and ONLY pull out order dates that are in 2013. Not the records that have 2013 and 2014 dates. If they have an order in 2013 AND 2014 then I want to exclude those records. So for example:
enter code here
Bill_Member_ID..........Order_Date
123....................01/05/2013
123.................... 01/27/2013
123.................... 02/15/2014
123.................... 02/18/2014
456.................... 01/07/2013
789.................... 01/05/2013
789.................... 02/17/2014
992.................... 03/15/2013
So then I should get a return of
Bill_Member_ID..........Order_Date
456.................... 01/07/2013
992.................... 03/15/2013
Thank you so much
What you need is a simple subselect, and to feed its results into your outermost select to display the results.
What you are after is the list of Bill_Member_ID who have an order date between 2013-01-01 and 2013-12-31 (inclusive) but do not have an order dates in between 2014-01-01 and 2014-12-13. So, let's build our pseudo-code select. We do this inside out (starting at the innermost, and working our way to the outermost layer of the select).
First up, generate a list of Members who have orders in 2014. So that's
Select Bill_Member_ID
From Order_Table
WHERE Year( OrderDate ) = '2014';
We feed that as a condition to the next select. This next layer's job is to select all the Members who have an OrderDate in 2013, but not in 2014.
Select Bill_Member_ID
From Order_Table
WHERE Year( OrderDate ) = '2013' AND Bill_Member_ID Not In
(
Select Bill_Member_ID
From Order_Table
WHERE Year( OrderDate ) = '2014'
)
This yields your list of Bill_Member_ID who have orders in 2013, but not in 2014. Add the additional columns you need for your final select. Also, add in your other filtering conditions (ie, the not Test and not Staff) to narrow the results as needed.
That's really all you need to do to generate your list of sought customers. If you aren't using a database that does not supports just specifying the year, then you'll need to use the between dates to filter the where date field in range of condition.