MDX union members in different hierarchies - mdx

What I want is to create a query that shows members from two different hierarchies side-by-side on the same axis. For example, something like this:
-----------------------------------------------------------------
| | Product |
-----------------------------------------------------------------
| Location | Total Amount | Qty of Product A | Qty of Product B |
-----------------------------------------------------------------
| USA | 9,249.23 | 2,382 | 1,009 |
-----------------------------------------------------------------
| UK | 9,998.09 | 5,282 | 5,129 |
-----------------------------------------------------------------
It’s clear we can get the results we need by running two different queries, as follows:
select
[Measures].[Sales Amount] on 0,
[Country].[USA],[Country].[UK] on 1
from [Cube]
where [Time].[Year].[2010]
select
crossjoin([Product].[Type].members, [Measures].[Sales Quantity]) on 0,
[Country].[USA],[Country].[UK] on 1
from [Cube]
where [Time].[Year].[2010]
I found this post http://blog.crossjoin.co.uk/2009/05/20/joining-the-results-of-two-mdx-queries-together which is helpful but is a little bit different from my case.
How can I use MDX get result which has different hierarchies members in the same axises?

Maybe something like this:
SELECT
{
([Product].[Type].[All], [Measures].[Sales Amount])
,{[Product].[Type].members * [Measures].[Sales Quantity]}
} ON 0,
[Country].[USA],[Country].[UK] ON 1
FROM[Cube]
WHERE [Time].[Year].[2010];

Related

Using DAX in PowerPivot to find out value of a column based on MAX / IF another

I'm trying to write a DAX formula that finds the maximum YearMonth and returns the liability IF the points earned are >0. So in the example below the returning value would be 190.
I've spent ages trying to get this to work without any luck, so if anyone can help I'd be really grateful
+-----------+---------------+-----------+
| YearMonth | Points Earned | Liability |
+-----------+---------------+-----------+
| 200506 | 86 | 170 |
| 200507 | 22 | 150 |
| 200508 | 45 | 190 |
| 200509 | 0 | 190 |
| 200510 | 0 | 190 |
+-----------+---------------+-----------+
*Apologies about the formatting of the table, I couldn't work out how to insert it correctly.
Create two measures MaxYearMonth and LastLiability.
MaxYearMonth :=
CALCULATE (
MAX ( [YearMonth] ),
FILTER ( ALL ( Table ), [Points Earned] > 0 )
)
LastLiability :=
CALCULATE (
SUM ( Table[Liability] ),
FILTER ( Table, Table[YearMonth] = [MaxYearMonth] )
)
The LastLiability measure calculates the Liability by using the MaxYearMonth measure. MaxYearMonth measure calculates the last YearMonth which Points Earned value is greater than 0.
Let me know if this helps.

SQL Query to return a distinct count of one column while allowing a full summation of a second column, grouped by a third

I'm writing a query in access 2010 and i can't use count(distinct... so I'm running into a bit of trouble with what can be found below:
An example of my table is as follows
Provider | Member ID | Dollars | Status
FacilityA | 1001 | 50 | Pended
FacilityA | 1001 | 100 | Paid
FacilityA | 1002 | 200 | Paid
FacilityB | 1005 | 30 | Pended
FacilityB | 1009 | 90 | Pended
FacilityC | 1001 | 100 | Paid
FacilityC | 1008 | 500 | Paid
I want to return the total # of unique members that have visited each facility, but I also want to get the total dollar amount that is Pended, so for this example the ideal output would be
Provider | # members | Total Pended charges
FacilityA | 2 | 50
FacilityB | 2 | 120
FacilityC | 2 | 0
I tried using some code I found here: Count Distinct in a Group By aggregate function in Access 2007 SQL
and here:
SQL: Count distinct values from one column based on multiple criteria in other columns
Copying the code from the first link provided by gzaxx:
SELECT cd.DiagCode, Count(cd.CustomerID)
FROM (select distinct DiagCode, CustomerID from CustomerTable) as cd
Group By cd.DiagCode;
I can make this work for counting the members:
SELECT cd.Provider_Number, Count(cd.Member_ID)
FROM (select distinct Provider_Number, Member_ID from Claims_Table) as cd
ON claims_table.Provider_Number=cd.Provider_Number
Group By cd.Provider_Number;
However, no matter what I try I can't get a second portion dealing with the dollars to work without causing an error or messing up the calculation on the member count.
SELECT cd.Provider_Number,
-- claims_table.Member_ID, claims_table.Dollars
SUM(IIF ( Claims_Table.Status = 'Pended' , Claims_Table.Dollars , 0 )) as Dollars_Pending,
Count(cd.Member_ID) as Uniq_Members,
Sum(Dollars) as Dollar_Wrong
FROM (select distinct Provider_Number, Member_ID from Claims_Table) as cd inner join #claims_table
ON claims_table.Provider_Number=cd.Provider_Number and claims_table.Member_ID = cd.Member_ID
Group By cd.Provider_Number;
This should work fine based only on the table you described (named Tabelle1):
SELECT Provider, count(MemberID) as [# Members],
NZ(SUM(SWITCH([Status]='Pended', Dollars)),0) as [Total pending charges]
FROM Tabelle1
GROUP BY Provider;
Explanation
I think the first and second column are self-explanatory.
The third column is where most things are done. The SWITCH([Status]='Pended', Dollars) returns the Dollars only if the status is pending. This then gets summed up by SUM. The NZ(..,0) will set the column to 0 if the SUM returns a NULL.
EDIT: This was tested on Access 2016

Select the difference of two consecutive columns

I have a table car that looks like this:
| mileage | carid |
------------------
| 30 | 1 |
| 50 | 1 |
| 100 | 1 |
| 0 | 2 |
| 70 | 2 |
I would like to get the average difference for each car. So for example for car 1 I would like to get ((50-30)+(100-50))/2 = 35. So I created the following query
SELECT AVG(diff),carid FROM (
SELECT (mileage-
(SELECT Max(mileage) FROM car Where mileage<mileage AND carid=carid GROUP BY carid))
AS diff,carid
FROM car GROUP BY carid)
But this doesn't work as I'm not able to use current row for the other column. And I'm quite clueless on how to actually solve this in a different way.
So how would I be able to obtain the value of the next row somehow?
The average difference is the maximum minus he minimum divided by one less than the count (you can do the arithmetic to convince yourself this is true).
Hence:
select carid,
( (max(mileage) - min(mileage)) / nullif(count(*) - 1, 0)) as avg_diff
from cars
group by carid;

Adding another column based on different criteria (SQL-server)

I do quite a bit of data analysis and use SQL on a daily basis but my queries are rather simple, usually pulling a lot of data which I thereafter manipulate in excel, where I'm a lot more experienced.
This time though I'm trying to generate some Live Charts which have as input a single SQL query. I will now have to create complex tables without the aid of the excel tools I'm so familiar with.
The problem is the following:
We have telesales agents that book appointments by answering to inbound calls and making outbound cals. These will generate leads that might potentially result in a sale. The relevant tables and fields for this problem are these:
Contact Table
Agent
Sales Table
Price
OutboundCallDate
I want to know for each telesales agent their respective Total Sales amount in one column, and their outbound sales value in another.
The end result should look something like this:
+-------+------------+---------------+
| Agent | TotalSales | OutboundSales |
+-------+------------+---------------+
| Tom | 30145 | 0 |
| Sally | 16449 | 1000 |
| John | 10500 | 300 |
| Joe | 50710 | 0 |
+-------+------------+---------------+
With the below SQL I get the following result:
SELECT contact.agent, SUM(sales.price)
FROM contact, sales
WHERE contact.id = sales.id
GROUP BY contact.agent
+-------+------------+
| Agent | TotalSales |
+-------+------------+
| Tom | 30145 |
| Sally | 16449 |
| John | 10500 |
| Joe | 50710 |
+-------+------------+
I want to add the third column to this query result, in which the price is summed only for records where the OutboundCallDate field contains data. Something a bit like (where sales.OutboundCallDate is Not Null)
I hope this is clear enough. Let me know if that's not the case.
Use CASE
SELECT c.Agent,
SUM(s.price) AS TotalSales,
SUM(CASE
WHEN s.OutboundCallDate IS NOT NULL THEN s.price
ELSE 0
END) AS OutboundSales
FROM contact c, sales s
WHERE c.id = s.id
GROUP BY c.agent
I think the code would look
SELECT contact.agent, SUM(sales.price)
FROM contact, sales
WHERE contact.id = sales.id AND SUM(WHERE sales.OutboundCallDate)
GROUP BY contact.agent
notI'm assuming your Sales table contains something like Units and Price. If it's just a sales amount, then replace the calculation with the sales amount field name.
The key thing here is that the value summed should only be the sales amount if the OutboundCallDate exists. If the OutboundCallDate is not NULL, then we're using a value of 0 for that row.
select Agent.Agent, TotalSales = sum (sales.Price*Units)
, OutboundSales = sum (
case when Outboundcalldate is not null then price*Units
else 0
end)
From Sales inner join Agent on Sales.Agent = Agent.Agent
Group by Agent.Agent

PHP Database Query - Group by month

An edit per the suggestions:
$sql=
"SELECT SysproCompanyJ.dbo.InvMovements.StockCode,
SysproCompanyJ.dbo.InvMaster.Description,
SysproCompanyJ.dbo.InvMovements.TrnYear,
SysproCompanyJ.dbo.InvMovements.Warehouse,
SysproCompanyJ.dbo.InvMovements.TrnMonth,
SysproCompanyJ.dbo.InvMovements.TrnQty,
SysproCompanyJ.dbo.InvMovements.TrnValue
FROM SysproCompanyJ.dbo.InvMovements,
SysproCompanyJ.dbo.InvMaster
WHERE SysproCompanyJ.dbo.InvMovements.StockCode = SysproCompanyJ.dbo.InvMaster.StockCode
AND SysproCompanyJ.dbo.InvMovements.Warehouse = 'S2'
GROUP BY SysproCompanyJ.dbo.InvMovements.TrnMonth";
The sample DB data would be:
Stockcode | Description | TrnYear | Warehouse | TrnMonth | TrnQty | TrnValue
PN1 | Part Number 1 | 2013 | S2 | 1 | 100 | 10.00
PN2 | Part Number 2 | 2013 | S2 | 1 | 200 | 125.00
PN3 | Part Number 3 | 2013 | S2 | 1 | 200 | 60.00
PN1 | Part Number 1 | 2013 | S2 | 2 | 300 | 560.00
PN4 | Part Number 4 | 2013 | S2 | 2 | 400 | 30.00
PN5 | Part Number 5 | 2013 | S2 | 2 | 100 | 230.00
I'm trying to break down the data into separate tables grouped by month and then having a variable to sum the total TrnValue by month.
The current query as is gives the following error
Warning: odbc_exec() [function.odbc-exec]: SQL error: [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'SysproCompanyJ.dbo.InvMovements.StockCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause., SQL state 37000 in SQLExecDirect in C:\wamp\www\dacs\S2_2.php on line 69
You can't use columns in the select statement unless they inside an aggregate function (min,max,sum,count,...) or are included in the Group By.
Try something like this:
SELECT SysproCompanyJ.dbo.InvMovements.Warehouse,
SysproCompanyJ.dbo.InvMovements.TrnYear,
SysproCompanyJ.dbo.InvMovements.TrnMonth,
Sum(SysproCompanyJ.dbo.InvMovements.TrnQty) as sum_TrnQty,
Sum(SysproCompanyJ.dbo.InvMovements.TrnValue) as sum_TrnValue
FROM SysproCompanyJ.dbo.InvMovements,
SysproCompanyJ.dbo.InvMaster
WHERE SysproCompanyJ.dbo.InvMovements.StockCode = SysproCompanyJ.dbo.InvMaster.StockCode
AND SysproCompanyJ.dbo.InvMovements.Warehouse = 'S2'
GROUP BY SysproCompanyJ.dbo.InvMovements.Warehouse,
SysproCompanyJ.dbo.InvMovements.TrnYear,
SysproCompanyJ.dbo.InvMovements.TrnMonth
Usually doesn't make sense to include varchar columns (Stockcode, Description) in any type of aggregate, and since they are different values, you probably don't want them in the Group By either.
When using GROUP BY in a SQL query, all fields shown should either be 'grouped' by or a calculated (aggregate) value.
For example;
SELECT city, count(*), avg(price) FROM properties GROUP BY city;
Which will produce something like;
City   |  count  |   Avg
Paris  |  3      |   166.666
Will count the number of rows per city. City is part of the 'group by'. 'count(*)' and 'avg(price)' are calculated columns(aggregate).
If we would introduce another column to the query, 'city';
SELECT country, city, count(*), avg(price) FROM properties GROUP BY city;
The query would give an error, because country is neither 'grouped' or a calculated value. This error is quite logical; city-names are not unique worldwide (e.g. 'Paris' USA and 'Paris' in France), so grouping by city alone, the database can not show a unique country name.
To resolve this, either include 'country' in the group by, or make it a calculated field;
SELECT country, city, count(*), avg(price) FROM properties GROUP BY country, city;
Will return the results grouped by country, then by city
Country | City | count | Avg
USA | Paris | 1 | 100.000
France | Paris | 2 | 200.000
Using a calculated value for country;
SELECT min(country), city, count(*), avg(price) FROM properties GROUP BY country, city;
Would return the results grouped by city, and the 'first' country in the group:
min(Country)| City | count | Avg
France | Paris | 3 | 166.666
Which is probably not logical; the results show 'France', but it includes results from Paris, USA