I am not sure how to put this but, trying to sum the values of an measure using MDX.
My MDX is as follows :
select {[CompanyDimension].[Foo],
[CompanyDimension].[Bar],
[CompanyDimension].[CDK]} on columns,
TopCount([${SLRDimension}].Children,
10,
[Measures].[ProjectCountMeasure]) on rows
from [Foo_Cube]
where ([FAreaDimension].[Admin])
For this expression, I am getting following output :
+----------------------------------------------------------------------+
| | CompanyDimension.NameHierarchy |
+----------------------------------------------------------------------+
| SLRDimension | Foo | Bar | CDK
+----------------------------------------------------------------------+
| Development | 1 | 1 | 6
| Testing | | | 3
| Implementation | | 1 | 5
| Reports | 1 | | 4
| Planning | 1 | | 5
| Reporting | | | 1
| Coding | | | 2
| Performance | | | 1
| Designed | | 1 |
| Designing | | | 2
+----------------------------------------------------------------------+
Now I want to get the sum of values per row. for example, in 1st row for Development, I want its corresponding value to be 7 instead of having 3 values i.e. 1, 1, 6
I am newbie to MDX world so I do not know how to do this. Please help !
I want final values as follows :
+----------------------------------------------------------------------+
| | CompanyDimension.NameHierarchy |
+----------------------------------------------------------------------+
| SLRDimension | Sum
+----------------------------------------------------------------------+
| Development | 7
| Testing | 3
| Implementation | 6
| Reports | 5
| Planning | 6
| Reporting | 1
| Coding | 2
| Performance | 1
| Designed | 1
| Designing | 2
+----------------------------------------------------------------------+
Using the Pentaho sample data SteelWheelsSales cube as basis, this is similar to what you have now:
SELECT NON EMPTY {[Customers].[All Customers]} ON ROWS,
NON EMPTY {[Markets].[APAC],[Markets].[EMEA]} ON COLUMNS
FROM [SteelWheelsSales]
and this is what you want:
SELECT NON EMPTY {[Customers].[All Customers]} ON ROWS,
NON EMPTY {[Measures].[Quantity]} ON COLUMNS
FROM [SteelWheelsSales]
WHERE {[Markets].[APAC],[Markets].[EMEA]}
notice how I replaced the columns with the measure I want to see, and how I moved the markets to the WHERE clause.
Related
I changed a but the context, but it's basically the same issue.
Imagine we are in a never-ending tunnel, shaped like a circle. We split every section of the circle, from 1 to 10 and we'll call each section slot (sl). There are 2 groups (gr) of living things walking in the tunnel. Each group has 2 bands, where each has a name and global hitpoints (hp). Every group is walking forward (although the bands might change order). If a group is at slot #10 and moves forward, he will be at slot #1. We snapshot their information every day. All the data gathered is stored in a table with this structure:
+----------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+--------------+--+
| day_id | | gr_1_sl_1_id | | gr_1_sl_1_name | | gr_1_sl_1_hp | | gr_1_sl_2_id | | gr_1_sl_2_name | | gr_1_sl_2_hp | | gr_2_sl_1_id | | gr_2_sl_1_name | | gr_2_sl_1_hp | | gr_2_sl_2_id | | gr_2_sl_2_name | | gr_2_sl_2_hp | |
+----------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+--------------+--+
| 1 | 3 | orc | 100 | 4 | goblin | 10 | 10 | human | 50 | 1 | dwarf | 25 | |
| 2 | 6 | goblin | 7 | 7 | orc | 76 | 2 | human | 60 | 3 | dwarf | 28 | |
+----------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+----------------+----------------+------------------+--------------+--+
As you can see, the columns are structured in a sequential way, while the data shows what is the actual value. What I want is to have the information shaped this way instead:
+---------+-------+-------+-----------+---------+
| id_game | gr_id | sl_id | band_name | band_hp |
+---------+-------+-------+-----------+---------+
| 1 | 1 | 3 | orc | 100 |
| 1 | 1 | 4 | goblin | 10 |
| 1 | 2 | 10 | human | 50 |
| 1 | 2 | 1 | dwarf | 25 |
| 2 | 1 | 6 | goblin | 7 |
| 2 | 1 | 7 | orc | 76 |
| 2 | 2 | 2 | human | 60 |
| 2 | 2 | 3 | dwarf | 28 |
+---------+-------+-------+-----------+---------+
I have this information in power bi, although I can create views in sql server if need be. I have tried many things, closest thing I got was unpivoting and parsing the original columns to get day_id, gr_id, sl_id, attributes and values. In attributes and values, it's basically name and hp with their corresponding value (I changed hp into string), but then I'm stocked, I'm not sure what to do next.
Anyone has any ideas ? Keep in mind that I oversimplified the problem; there are more groups, more slots, more bands and more statistics (i.e. attack and defense rating, etc.)
You seem to want to unpivot the table. In SQL Server, I recommend using apply:
select t.day_id, v.*
form t cross apply
(values (1, 1, gr_1_sl_1_id, gr_1_sl_1_name, gr_1_sl_1_hp),
(1, 2, gr_1_sl_2_id, gr_1_sl_2_name, gr_1_sl_2_hp),
(2, 1, gr_2_sl_1_id, gr_1_sl_1_name, gr_2_sl_1_hp),
(2, 2, gr_2_sl_2_id, gr_1_sl_2_name, gr_2_sl_2_hp)
) v(id_game, gr_id, sl_id, band_name, band_hp);
In other databases, you can do something similar with union all.
I'm trying to figure out how to put together a SQL statement that will let me find an end-item in our database based on its bill of materials. I guess you could say this is like a reverse BOM lookup question.
My table structure is pretty simple.
-End-item table
-Component table
-Linking table to tie together multiple components to an end item record.
The data I have is just the component list, and I want to find the end item. Since every bill of material is unique it has to match the bill of materials perfectly ie exact number of components and exact matches to the component SKU numbers. In some cases 2 end-items might use all the same components, but one of them just uses an extra part or two that makes the end-item SKU number different, so it has to account for that. That is, again, it has to match the BOM perfectly.
If not an outright answer, could someone at least steer me on the correct path to finding one?
------ UPDATE ----------
Table structure would be something like this.
ManufacturedPart
,--------------------,
| ID | PART_NUM |
|--------------------|
| 1 | V3175-01 |
| 2 | V3367-01 |
| 3 | V3988-01 |
| 4 | V3175-CV |
`--------------------`
Component
,--------------------,
| ID | COMP_NUM |
|--------------------|
| 1 | V3175 |
| 2 | V3367 |
| 3 | V3369 |
| 4 | V3114 |
| 5 | V3370 |
| 6 | V4060 |
| 7 | V3550 |
| 8 | V3988 |
`--------------------`
ManufacturedComponent
,-------------------------------------------------,
| ID | MANUFACTURED_PART_ID | COMPONENT_ID |
|-------------------------------------------------|
| 1 | 1 | 1 |
| 2 | 1 | 4 |
| 3 | 1 | 6 |
| 4 | 2 | 2 |
| 5 | 2 | 3 |
| 6 | 2 | 5 |
| 7 | 2 | 7 |
| 8 | 3 | 1 |
| 9 | 3 | 8 |
| 10 | 4 | 1 |
| 11 | 4 | 4 |
`-------------------------------------------------`
Assuming I have only the COMP_NUMs (component numbers) to search with I want to match back to the ManufacturedPart that contains that exact list of components.
So some examples: If I have components V3175, V3114, and V4060, it should match back to V3175-01 manufactured part. But, if I only have components V3175 and V3114 it should match back to V3175-CV manufactured part. If I have components V3367, V3369, V3370, and V3550 it should match back to manufactured part V3367-01.
I have no SQL written at all yet as I'm unsure of how to break the problem down..
I have a master table (Project List) along with several sub tables that are joined on one common field (RecNum). I need to get totals for all of the sub tables, by column and am not sure how to do it. This is a sample of the table design. There are more columns in each table (I need to pull * from "Project List") but I'm showing a sampling of the column names and values to get an idea of what to do.
Project List
| RecNum | Project Description |
| 6 | Sample description |
| 7 | Another sample |
WeekA
| RecNum | UserName | Day1Reg | Day1OT | Day2Reg | Day2OT | Day3Reg | Day3OT |
| 6 | JustMe | 1 | 2 | 3 | 4 | 5 | 6 |
| 6 | NotMe | 1 | 2 | 3 | 4 | 5 | 6 |
| 7 | JustMe | | | | | | |
| 7 | NotMe | | | | | | |
WeekB
| RecNum | UserName | Day1Reg | Day1OT | Day2Reg | Day2OT | Day3Reg | Day3OT |
| 6 | JustMe | 7 | 8 | 1 | 2 | 3 | 4 |
| 6 | NotMe | 7 | 8 | 1 | 2 | 3 | 4 |
| 7 | JustMe | | | | | | |
| 7 | NotMe | | | | | | |
So the first query should return the complete totals for both users, like this:
| RecNum | Project Description | sumReg | sumOT |
| 6 | Sample description | 40 | 52 |
| 7 | Another sample | 0 | 0 |
The second query should return the totals for just a specified user, (WHERE UserName = 'JustMe') like this:
| RecNum | Project Description | sumReg | sumOT |
| 6 | Sample description | 20 | 26 |
| 7 | Another sample | 0 | 0 |
Multiple parallel tables with the same structure is usually a sign of poor database design. The data should really be all in one table, with additional columns specifying the week.
You can, however, use union all to bring the data together. The following is an example of a query:
select pl.recNum, pl.ProjectDescription,
sum(Day1Reg + Day2Reg + Day3Reg) as reg,
sum(Day1OT + Day2OT + Day3OT) as ot
from ProjectList pl join
(select * from weekA union all
select * from weekB
) w
on pl.recNum = w.recNum
group by l.recNum, pl.ProjectDescription,;
In practice, you should use select * with union all. You should list the columns out explicitly. You can add appropraite where clauses or conditional aggregation to get the results you want in any particular case.
Please forgive my woefully limited understanding of SQL, but I'm hoping someone can help me. I need to alter a query written by someone else some time ago.
The query displays consumption per industry for a variety of industries in a number of areas. The table it spits out currently looks something like this:
+---------------+----------+---------+
| Economic area | Industry | Total |
+---------------+----------+---------+
| Area1 | | |
| | Ind1 | 459740 |
| | Ind2 | 43000 |
| | Ind3 | 0 |
| | Total | 502740 |
| Area2 | | |
| | Ind1 | 725560 |
| | Ind2 | 111017 |
| | Ind3 | 277577 |
| | Total | 1114154 |
+---------------+----------+---------+
Unfortunately, this table in conjunction with another table we publish on the number of producers in each industry and area can reveal commercially sensitive information when there are very few producers. For instance, in the table below, there's only one producer in Industry 2 in Area 1, so everything in the above table consumed by industry 2 in Area 1 goes to that producer.
+---------------+---------+------+------+------+
| Economic area | County | Ind1 | Ind2 | Ind3 |
+---------------+---------+------+------+------+
| Area1 | | | | |
| | county1 | 1 | 0 | 0 |
| | county2 | 3 | 1 | 2 |
| | county3 | 1 | 0 | 0 |
| | Total: | 5 | 1 | 2 |
| | | | | |
| Area2 | county4 | 5 | 0 | 1 |
| | county5 | 3 | 3 | 1 |
| | county6 | 1 | 0 | 1 |
| | county7 | 0 | 0 | 0 |
| | Total: | 9 | 3 | 3 |
+---------------+---------+------+------+------+
What I've been asked to do is to produce a condensed version of the first table that looks like the one below, where industries that have less than 3 producers in an area are aggregated into a generic Other Industry. Something like this:
+---------------+----------+--------+
| Economic area | Industry | All |
+---------------+----------+--------+
| Area1 | | |
| | Ind1 | 459740 |
| | OtherInd | 121376 |
| | Total | 581116 |
| Area2 | | |
| | Ind1 | 725560 |
| | Ind2 | 111017 |
| | Ind3 | 244 |
| | Total | 836821 |
+---------------+----------+--------+
I have been searching for a while, but haven't been able to find anything that works, or that I can understand well enough to make it work. I tried using a Count(Case(industry_code<3,1,0))... but I'm working in MS Access, so that doesn't work. I thought about using and IIF or a Switch statement, but it doesn't seem like either of those allow for the right type of comparison. I also found where someone suggested a From statement that had two different groupings - but Access spat out an error when I tried it.
The only marginal success I've had is with a HAVING (((Count(Allmills.industry_code))>3)), but it just drops the problem industries completely.
Currently the a somewhat simplified version of the query looks like this:
SELECT
economic_areas.economic_area AS [Economic area],
Industry_codes.industry_heading AS Industry,
Sum(Allmills.consumption) AS [All],
Sum(Allmills.[WA origin logs]) AS Washington
Allmills.industry_code,
Count(Allmills.industry_code) AS CountOfindustry_code,
Sum(Allmills.industry_code) AS SumOfindustry_code
FROM ((economic_areas INNER JOIN Allmills ON (economic_areas.state_abbrev =
Allmills.state_abbrev)
AND (economic_areas.economic_area_code = Allmills.economic_area_code))
INNER JOIN Industry_codes ON Allmills.display_industry_code =
Industry_codes.industry_code)
WHERE (((Allmills.economic_area_code) Is Not Null))
GROUP BY Allmills.display_industry_economic_area_code,
Allmills.display_industry_code, economic_areas.economic_area,
Industry_codes.industry_heading, Allmills.industry_code
ORDER BY Allmills.display_industry_economic_area_code,
Allmills.display_industry_code;
Any help would be greatly appreciated, even just suggestions of what types of techniques might be useful that I can look into elsewhere - I'm just running in circles right now.
HAVING is really solution here - change your query to use HAVING with > 3, add another query with HAVING <= 3, then UNION ALL the results of them
I'm trying to set up a report based on several tables.
I have a table Actual that looks like this:
+--------+------+
| status | date |
+--------+------+
| 5 | 7/10 |
| 8 | 7/9 |
| 8 | 7/11 |
| 5 | 7/18 |
+--------+------+
Table Targets looks like this:
+--------+-------------+--------+------------+
| status | weekEndDate | target | cumulative |
+--------+-------------+--------+------------+
| 5 | 7/12 | 4 | 45 |
| 5 | 7/19 | 5 | 50 |
| 8 | 7/12 | 4 | 45 |
| 8 | 7/19 | 5 | 50 |
+--------+-------------+--------+------------+
Grouping the Actual records by which Targets.weekEndDate they fall under, I have the following aggregate query GroupActual:
+-------------+------------+--------------+--------+------------+
| weekEndDate | status | weeklyTarget | actual | cumulative |
+-------------+------------+--------------+--------+------------+
| 7/12 | 5 | 4 | 1 | 45 |
| 7/12 | 8 | 4 | 2 | 41 |
| 7/19 | 5 | 5 | 1 | 50 |
| 7/19 | 8 | 4 | | 45 |
+-------------+------------+--------------+--------+------------+
I'm trying to create this report:
+--------+------------+------+------+
| status | category | 7/12 | 7/19 | ...etc for every weekEndDate entry in Targets
+--------+------------+------+------+
| 5 | actual | 1 | 1 |
| 5 | target | 4 | 5 |
| 5 | cumulative | 45 | 50 |
+--------+------------+------+------+
| 8 | actual | 2 | |
| 8 | target | 4 | 5 |
| 8 | cumulative | 45 | 50 |
+--------------+------+------+------+
I can use a crosstab query to make the date columns, but I'm not sure how to have rows for "actual", "target", and "cumulative". They aren't values in the same table, which means (I think) that a crosstab query won't be useful for this breakdown. Should I try to change GroupActual so that it puts the data in the shape I'm looking for? Kind of confused as to where to go next with this...
EDIT: I've made some headway on the crosstabs as per PowerUser's solution, but I'm having trouble with the one for Target. I modified the wizard's generated SQL in an attempt to get what I want but it's not working out. I used a version of GroupActual that only has the weekEndDate,status, and weeklyTarget columns; here's the SQL:
TRANSFORM weeklyTarget
SELECT status
FROM TargetStatus_forCrosstab_Target
GROUP BY status,weeklyTarget
PIVOT Format([weekEndDate],"Short Date");
You're almost there. The problem is that you can't do this all in a single crosstab. You need to make 3 crosstabs (one for 'actual', one for 'target', and one for 'cumulative'), then make a Union query to combine them all.
Additional Tip: In your individual crosstabs, add a Sort column. Your 'actual' crosstab will have a Sort value of 1, 'Target' will have a Sort value of 2, and 'Cumulative' will have 3. That way, when you union them together, you can get them all in the right order.