Grouping in MDX Query - join

I am very newbie to MDX world..
I want to group the Columns based on only 3 rows. But, need join for 4th row also..
My query is :
SELECT
( {
[Measures].[Live Item Count]
}
) DIMENSION PROPERTIES parent_unique_name ON COLUMNS,
Crossjoin(
crossjoin(
[Item].[Class].&[Light],
[Item].[Style].&[Fav]
[Item].[Season Year].members),
[Item].[Count].children ) on rows
FROM Cube
Output comes as :
Light(Row) | FAV(Row) | ALL(Row) | 16(Row) | 2(col)
Light(Row) | FAV(Row) | ALL(Row) | 7(Row) | 1(col)
Light(Row) | FAV(Row) | 2012(Row) | 16(Row)| 2(col)
Light(Row) | FAV(Row) | 2011(Row) | 7(Row) | 1(col)
But, I want my output to be displayed as:
Light(Row) | FAV(Row) | ALL(Row) | | 3(col)
Light(Row) | FAV(Row) | 2012(Row) | 16(Row)| 2(col)
Light(Row) | FAV(Row) | 2011(Row) | 7(Row) | 1(col)
i.e., I want to group my first two rows such that there is no duplicate 'ALL' in 3rd column..
Thanks in advance

Try this - using the level name Season Year with the Attribute name Season Year will pick up every member without teh ALL member:
SELECT
( {
[Measures].[Live Item Count]
}
) DIMENSION PROPERTIES parent_unique_name ON COLUMNS,
Crossjoin(
crossjoin(
[Item].[Class].&[Light],
[Item].[Style].&[Fav]
[Item].[Season Year].[Season Year].members),
[Item].[Count].children ) on rows
FROM Cube

You can use this query if there is an All member on the [Item].[Count] hierarchy:
SELECT {[Measures].[Live Item Count]} DIMENSION PROPERTIES parent_unique_name ON COLUMNS,
Crossjoin(
Crossjoin([Item].[Class].&[Light], [Item].[Style].&[Fav]),
Union(
Crossjoin({"All member of [Item].[Season Year]"}, {"All member of [Item].[Count]"}),
Crossjoin(Except([Item].[Season Year].members, {"All member of [Item].[Season Year]"}), [Item].[Count].children),
) ON ROWS
FROM Cube

Related

Conditionally CONCAT based on helper column data using ARRAYFORMULA in Google Sheets

I have 2 columns of names (Name 1, Name 2) which I would like to concat into a single column.
[CURRENT DATA SET] [FORMULA - CONCAT]
| A | B | | D |
| Name1 | Name2 | | Name1_Name2 |
| Name3 | Name4 | | Name3_Name4 |
| Name5 | Name6 | | Name5_Name6 |
This portion is working using my ARRAYFORMULA:
=ARRAYFORMULA(
IF(
ISBLANK(B4:B),
CONCAT(A4:A,B4:B),
CONCAT(A4:A,("_"&B4:B))
)
)
Here is the issue: Sometimes I need the CONCAT formula to put column B first, then Colum A (Example Name2_Name1).
Objective: The CONCAT formula needs to be conditional based on a helper column containing the list of valid name options.
Logic:
If helper column matches CONCAT, CONCAT ColumnA_ColumnB.
If helper column does not match CONCAT, ColumnB_ColumnA.
If still does not match, leave blank.
Expected Results using a helper column
[CURRENT DATA SET] [Helper Column] [EXPECTED RESULTS]
| A | B | | C | | D |
| Name1 | Name2 | | Name1_Name2 | | Name1_Name2 |
| Name3 | Name4 | | Name6_Name5 | | Name3_Name4 |
| Name5 | Name6 | | Name3_Name4 | | Name6_Name5 |
| Name7 | | | Name5 | | |
| Name5 | | | Name8 | | Name5 |
Is it possible to create an arrayformula to achieve these expected results?
Here is my Google Sheet: Click Here
See if this works for you:
=ArrayFormula(IFERROR(IFERROR(VLOOKUP(A4:A&IF(LEN(B4:B), "_"&B4:B,), D4:D, 1, 0), VLOOKUP(IF(LEN(B4:B), B4:B&"_",)&A4:A, D4:D, 1, 0))))

How to translate COUNTIFS formula in ARRAYFORMULA to automatically insert the formula in each row

With my countifs formula in column C I want to auto-number (running total) all occurrences of an identical string in column A (e.g. Apple or Orange) but only if on the same row where the string appears column B is of a certain type, e.g. if in column B the type is of "fruit" in column C auto number all occurrences of an identical string in column A. For each new string which is of type "fruit" start the numbering all over again.
The outcome should be like this:
+---+-----------+-------+---+--+
| | A | B | C | |
+---+-----------+-------+---+--+
| 1 | Apple | Fruit | 1 | |
| 2 | Apple | Fruit | 2 | |
| 3 | Mercedes | Car | 0 | |
| 4 | Mercedes | Car | 0 | |
| 5 | Orange | Fruit | 1 | |
| 6 | Orange | Fruit | 2 | |
| 7 | Apple | Fruit | 3 | |
+---+-----------+-------+---+--+
The formula in column C:
=COUNTIFS($A1:$A$1;A1;$B1:$B$1;"Fruit")
=COUNTIFS($A$1:$A2;A2;$B$1:$B2;"Fruit")
=COUNTIFS($A$1:$A3;A3;$A$1:$A3;"Fruit")
…and so on…
I want to translate this formula into an array formula and put this into the header so the formula will automatically expand.
No matter what I've tried it won't work.
Any help is truly appreciated!
Here's a link to a sheet: [https://docs.google.com/spreadsheets/d/1lgbuLbTSnyKkqr33NdVuDEv5eoXFwatX1rgeF9YpIks/edit?usp=sharing][1]
={"ARRAYFORMULA HERE"; ARRAYFORMULA(IF(LEN(B2:B), IF(B2:B="Fruit",
MMULT(N(ROW(B2:B)>=TRANSPOSE(ROW(B2:B))), N(B2:B="Fruit"))-
HLOOKUP(0, MMULT(N(ROW(B2:B)>TRANSPOSE(ROW(B2:B))), N(B2:B="Fruit")),
MATCH(VLOOKUP(ROW(B2:B), IF(N(B2:B<>B1:B), ROW(B2:B), ), 1, 1),
VLOOKUP(ROW(B2:B), IF(N(B2:B<>B1:B), ROW(B2:B), ), 1, 1), 0), 0), 0), ))}
demo spreadsheet
=ARRAYFORMULA(IF(LEN(B2:B), IF(B2:B="Fruit",
MMULT(N(ROW(B2:B)>=TRANSPOSE(ROW(B2:B))), N(B2:B="Fruit")), 0), ))

Query values from single column and fill columns, both based on multiple criteria

I am trying to query solely the IDs of clients that meet specific criteria from a source tab to an output tab and fill 2 columns with static values and 2 columns with dynamic values, based on criteria.
In the source tab I have:
+-----------------------+------+
| Status | ID |
+-----------------------+------+
| Retired/Deceased | 2a33 |
+-----------------------+------+
| Liquidation | 1sTR |
+-----------------------+------+
| Dissolved | 3B76 |
+-----------------------+------+
| Released from company | 463z |
+-----------------------+------+
| Active | 557g |
+-----------------------+------+
| In progress | zz34 |
+-----------------------+------+
| Demo | cc56 |
+-----------------------+------+
Please note, that there are 7 criteria values and I need the output for only 4 of them. Meaning that I need 4 values, based on which there will be binary fill of dynamic columns. The other 3 values are obsolete.
From these 4 values, if I have eg. Criteria 1, then I will have one fill of the 2 dynamic columns, if not (for the other 3 values) I will have other fill values.
So I guess simply going with a binary solution for the selection of the specific values is not applicable.
In the output tab logic:
+--------------------------------------------------------------------------------+
| Output tab |
+--------------------------------------------------------------------------------+
| ID | Status | Reason | Comment | Detail |
+----+--------+--------+----------------------------+----------------------------+
| A1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| B1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| C1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, else | then value 1, |
| | | | criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| D1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| E1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| F1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
| G1 | Static | Static | If criteria = criteria 1, | If criteria = criteria 1, |
| | | | then null, | then value 1, |
| | | | else criteria value | else value 2 |
+----+--------+--------+----------------------------+----------------------------+
Dummy output tab:
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
| Status | ID | Status | Reason | Comment | Detail |
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
| Retired/Deceased | 2a33 | Unable to proceed | Unspecified | Retired/Deceased | Retired/No longer in business |
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
| Liquidation | 1sTR | Unable to proceed | Unspecified | Liquidation | Retired/No longer in business |
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
| Dissolved | 3B76 | Unable to proceed | Unspecified | Dissolved | Retired/No longer in business |
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
| Released from company | 463z | Unable to proceed | Unspecified | (null) | No longer works for the company |
+-----------------------+------+-------------------+-------------+------------------+---------------------------------+
The column 'Status' is not required. I added it just for reference and readability.
Apologies, but I have corporate security restrictions for sharing links to Google Sheets.
The part that I struggle most with is that in column 4 (the first one from the dynamic ones) needs to return the value of the criteria from column 2 from the source tab.
So far I have worked my way around the first part of the query, where I QUERY the IDs based on multiple criteria, labelled and filled the static values columns.
=QUERY(Data!$A$3:$BN,
"SELECT B, 'Unable to proceed', 'Unspecified'
WHERE A = 'Retired/Deceased'
OR A = ''Liquidation'
OR A = 'Dissolved'
OR A = 'Released from company'
AND A IS NOT NULL
LABEL 'Unable to proceed' 'Unspecified' , 'Status' 'Reason'", 1)
However, I am struggling with the dynamic columns, based on multiple criteria.
I looked up ARRAYFORMULA with IFERROR and VLOOKUP in a nested QUERY, but was not able to work my way around it.
Also, I am quite interested in how this would work if there were more than 2 options of values to fill columns 3 and 4 in the output tab.
As far as I know, the way to work around 2 values based on criteria is to nest an IFERROR function to make it binary. But what if there were more than 2 values to fill the arrays with?
based on status:
=QUERY({QUERY(Data!$A$1:$B,
"SELECT B, 'Unable to proceed', 'Unspecified'
WHERE A = 'Retired/Deceased'
OR A = 'Liquidation'
OR A = 'Dissolved'
OR A = 'Released from company'
AND A IS NOT NULL
LABEL 'Unable to proceed''Status', 'Unspecified''Reason'", 1),
QUERY(ARRAYFORMULA(IFERROR(VLOOKUP(
QUERY(Data!$A$2:$B,
"SELECT A
WHERE A = 'Retired/Deceased'
OR A = 'Liquidation'
OR A = 'Dissolved'
OR A = 'Released from company'
AND A IS NOT NULL", 0),
{"Retired/Deceased", "Retired/Deceased", "Retired/No longer in business";
"Liquidation", "Liquidation", "Retired/No longer in business";
"Dissolved", "Dissolved", "Retired/No longer in business";
"Released from company", "", "No longer works for the company"}, {2, 3}, 0), )),
"LABEL Col1 'Comment', Col2 'Detail'", 0)}, , 0)
based on ID:
=QUERY({QUERY(Data!$A$1:$B,
"SELECT B, 'Unable to proceed', 'Unspecified'
WHERE A = 'Retired/Deceased'
OR A = 'Liquidation'
OR A = 'Dissolved'
OR A = 'Released from company'
AND A IS NOT NULL
LABEL 'Unable to proceed''Status', 'Unspecified''Reason'", 1),
QUERY(ARRAYFORMULA(IFERROR(VLOOKUP(
QUERY(Data!$A$2:$B,
"SELECT B
WHERE A = 'Retired/Deceased'
OR A = 'Liquidation'
OR A = 'Dissolved'
OR A = 'Released from company'
AND A IS NOT NULL", 0),
{"2a33", "Retired/Deceased", "Retired/No longer in business";
"1sTR", "Liquidation", "Retired/No longer in business";
"3B76", "Dissolved", "Retired/No longer in business";
"463z", "", "No longer works for the company"}, {2, 3}, 0), )),
"LABEL Col1'Comment', Col2'Detail'", 0)}, , 0)

How to get the index of FOREACH iterations

Within a FOREACH statement [e.g. day in range(dayX, dayY)] is there an easy way to find out the index of the iteration ?
Yes, you can.
Here is an example query that creates 8 Day nodes that contain an index and day:
WITH 5 AS day1, 12 AS day2
FOREACH (i IN RANGE(0, day2-day1) |
CREATE (:Day { index: i, day: day1+i }));
This query prints out the resulting nodes:
MATCH (d:Day)
RETURN d
ORDER BY d.index;
and here is an example result:
+--------------------------+
| d |
+--------------------------+
| Node[54]{day:5,index:0} |
| Node[55]{day:6,index:1} |
| Node[56]{day:7,index:2} |
| Node[57]{day:8,index:3} |
| Node[58]{day:9,index:4} |
| Node[59]{day:10,index:5} |
| Node[60]{day:11,index:6} |
| Node[61]{day:12,index:7} |
+--------------------------+
FOREACH does not yield the index during iteration. If you want the index you can use a combination of range and UNWIND like this:
WITH ["some", "array", "of", "things"] AS things
UNWIND range(0,size(things)-2) AS i
// Do something for each element in the array. In this case connect two Things
MERGE (t1:Thing {name:things[i]})-[:RELATED_TO]->(t2:Thing {name:things[i+1]})
This example iterates a counter i over which you can use to access the item at index i in the array.

laravel join table if data exists

What is the best way to join table A with table B, if table B has data and if not just give me data from table A? because if I do it in this way, and there are no photos in table B I don't get data from that row from table A.
$data = Category::join('photos', 'categories.cover_id', '=', 'photos.id')
->get(['categories.id',
'categories.position',
'categories.visible',
'categories.created_at',
'categories.updated_at',
'categories.title',
'photos.filename']);
return $data;
my idea is just to make another request to get all data from table A where categories.cover_id is 0 (without join)
my tables are just
table A (categories)
-------------------------------
| id | title | cover_id | ... |
-------------------------------
| 1 | lorem | 1 | ... |
-------------------------------
| 2 | ipsum | 12 | ... |
-------------------------------
| 3 | dolor | 0 | ... |
-------------------------------
table B (Photos, there is no data for dolor, because i created dolor recently in table A)
---------------------------------
| id | title | filename | ... |
---------------------------------
| 1 | lorem | lorem.jpg | ... |
---------------------------------
| .. | ..... | ...jpg | ... |
---------------------------------
| 12 | ipsum | ipsum.jpg | ... |
---------------------------------
You should be fine by just using a leftJoin(). A normal ("inner join") will only return results from both tables. But a left join returns all results from the left table (in this case categories) and everything that exists from the other table.
$data = Category::leftJoin('photos', 'categories.cover_id', '=', 'photos.id')
->get(['categories.id',
'categories.position',
'categories.visible',
'categories.created_at',
'categories.updated_at',
'categories.title',
'photos.filename']);
Or you could...
Use the power of Eloquent
You only need to define the relationship (I assume you already have a Photo model) and this gets a lot easier
class Category extends Eloquent {
public function photos(){
return $this->hasMany('Photo', 'cover_id');
}
}
And then...
$data = Category::with('photos')->get();
And you will have the photos model nested inside the category models. Accessible like this:
foreach($data as $category){
foreach($category->photos as $photo){
echo $photo->filename;
}
}
I would rather do it this way:
// Just assuming a few variables for better understanding
$allCategories = Category::all();
foreach ($allCategories as $category) {
$photo = Photo::find($category->cover_id);
if ($photo) { // $photo!=null or isset($photo) - you can use anything
// photo is found do the additional processing
}
//proceed with your normal processing
}

Resources