Pivot Table with merged date fields - pivot-table

I have a source data sheet, each data item having two date fields, startDate and endDate. What I would like to to in excel is generate a pivot table with row headers for each date from either of these columns, and two summary columns, one for Count Started, the other Count Ended.
For example, the following source data:
ItemId | startDate | endDate
1 | 6/1/16 | 6/2/16
2 | 6/2/16 | 6/3/16
3 | 6/1/16 | 6/3/16
Would produce a pivot table like this:
Date | Started | Ended
6/1/16 | 2 | 0
6/2/16 | 1 | 1
6/3/16 | 0 | 2

I doubt I would choose a PivotTable solution for this (that's unlike me!) but I think possible with a PT:
1) Create a PT from multiple consolidation ranges (example here) with ranges A:B and A:C (assuming ItemID is in A1).
2) After 7. select ColumnsA:C (in the new sheet) and apply Remove Duplicates (with all Columns checked).
3) Create a new PT from what remains (Column for COLUMNS, Value for ROWS, Count of Row for VALUES)
4) Right-click on startDate, Move, and click on first option.
5) In PivotTable Options..., Totals & Filters uncheck both Grand Totals and in Layout & Format, Format, check For empty cells show and enter 0.
6) Adjust labels to suit.

Related

Counting aggregated and then getting average

So, I am sure it's got to be simple, but, I cannot get Google Data Studio to provide an average of two aggregated columns. Example:
+----------+----------+
| Column 1 | Column 2 |
+----------+----------+
| A | TRUE |
| A | FALSE |
| B | TRUE |
| C | FALSE |
| A | TRUE |
| C | TRUE |
| B | FALSE |
| B | TRUE |
+----------+----------+
How can you get a count of the total value of A in Column 1 and divide it by the total number of TRUE in Column 2? I have tried Count(Column 1)/Count (Column 2) but it gives me the totals for the other values as well.
I have tried creating a new field with a CASE statement, but there is an error when trying to divide the two resulting CASE WHEN values:
CASE
WHEN Column 1 = A THEN 1
ELSE 0
END
The below shows two approaches of achieving the required calculation:
Approach 1: Ratio Metrics
Using Scorecards, Filters and Ratio Metrics:
1) Column 1 (A) Scorecard
- Add a Scorecard;
- Drag and Drop the field Column 1 onto the Metric field and change the aggregation to COUNT;
- Create and apply the Filter: Include Column 1 RegExp Match A
2) Column 2 (TRUE) Scorecard
- Add a Scorecard;
- Drag and Drop the field Column 2 onto the Metric field and change the aggregation to COUNT;
- Create and apply the Filter: Include Column 2 RegExp Match TRUE
3) Ratio Metric
- Select both Scorecards: Click on the Column 1 (A) Scorecard and then Ctrl + Click on the Column 2 (TRUE) Scorecard Scorecard;
- Blend Data: Right click on one of the selected Scorecards and select Blend data from the Drop-down.
Google Data Studio Report to demonstrate, as well as a GIF showing the process:
Approach 2: CASE Statements
An approach with CASE statements (create formula #1 and #2 at the Data Source-level; formula 3 can be created at the Data Source-level or Chart-level if required):
1) Column 1 (A)
CASE
WHEN REGEXP_MATCH(Column 1, "A") THEN "A"
ELSE NULL
END
2) Column 2 (TRUE)
CASE
WHEN REGEXP_MATCH(Column 2, "TRUE") THEN "TRUE"
ELSE NULL
END
3) Column 1 (A) / Column 2 (TRUE)
COUNT(Column 1 (A)) / COUNT(Column 2 (TRUE))
Added a New Page to the Google Data Studio Report to demonstrate as well as a GIF showing the process above:

Use excel to summarise data from a column by identifier

I have a spreadsheet with a column called MRN (the identifier) and the drugs administered next to them. There are duplicates of the MRN in column A that correspond to different courses of drugs. What I'm hoping to do is to summarise all the drugs administered associated with one MRN in one line, removing all duplicates. It looks something like this.
| | A | B |
| 1 | MRN Item
| 2 | 1 cefoTAXime
| 3 | 1 ampicillin
| 4 | 1 cefoTAXime
| 5 | 1 vancomycin
| 6 | 1 cefTRIaxone
| 7 | 2 ampicillin
| 8 | 2 vancomycin
| 9 | 2 vancomycin
I have 3 different formulas. The first is to produce a list of MRNs that are all unique. The second is to pull all drugs by MRN and list them in one line. The third is to remove duplicates from this list. They are below (in order).
{=IFERROR(INDEX($A$2:$A$2885, MATCH(0,COUNTIF(D$1:$D1, $A$2:$A$2885),0 )),"")}
{=INDEX($A$2:$B$2885,SMALL(IF($A$2:$A$2885=$D2,ROW($A$2:$A$2885)),COLUMN(D:D))-4,2)}
{=IFERROR(INDEX($E$2:$AE$2, MATCH(0,COUNTIF(D$3:$D3, $E$2:$AE$2),0 )),"")}
*I know that I can edit the second one by adding IF(ISERROR ...) to remove NA and print blanks if drug not found, but want to keep the formulas as simple as possible at this time.
My problem is that second formula isn't pulling all the drugs by MRN, and in an ideal world I would be able to combine the second and third formula into one, but I am not sure how to. Here is a link to a test file that shows my issue and the formulas in action.
https://1drv.ms/x/s!ApoCMYBhswHzhooXnumW2iV7yx-JaA
I appreciate that there may be a better way to do this using python/R, and if that's possible then I'm more than happy to try, but I couldn't make any headway. Thanks for your help and suggestions.
If you could deal with a count of the number of courses per drug per MRN, you can do this with Power Query (aka Get & Transform in Excel 2016)
Starting with the data you provided on your worksheet, the results would look like:
M-Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"MRN", Int64.Type}, {"Item", type text}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"MRN"}, {{"Count", each _, type table}}),
#"Expanded Count" = Table.ExpandTableColumn(#"Grouped Rows", "Count", {"MRN", "Item"}, {"Count.MRN", "Count.Item"}),
#"Pivoted Column" = Table.Pivot(#"Expanded Count", List.Distinct(#"Expanded Count"[Count.Item]), "Count.Item", "Count.MRN", List.NonNullCount)
in
#"Pivoted Column"

Find valid combinations based on matrix

I have a in CALC the following matrix: the first row (1) contains employee numbers, the first column (A) contains productcodes.
Everywhere there is an X that productitem was sold by the corresponding employee above
| 0302 | 0303 | 0304 | 0402 |
1625 | X | | X | X |
1643 | | X | X | |
...
We see that product 1643 was sold by employees 0303 and 0304
What I would like to see is a list of what product was sold by which employees but formatted like this:
1625 | 0302, 0304, 0402 |
1643 | 0303, 0304 |
The reason for this is that we need this matrix ultimately imported into an SQL SERVER table. We have no access to the origins of this matrix. It contains about 50 employees and 9000+ products.
Thanx for thinking with us!
try something like this
;with data as
(
SELECT *
FROM ( VALUES (1625,'X',NULL,'X','X'),
(1643,NULL,'X','X',NULL))
cs (col1, [0302], [0303], [0304], [0402])
),cte
AS (SELECT col1,
col
FROM data
CROSS apply (VALUES ('0302',[0302]),
('0303',[0303]),
('0304',[0304]),
('0402',[0402])) cs (col, val)
WHERE val IS NOT NULL)
SELECT col1,
LEFT(cs.col, Len(cs.col) - 1) AS col
FROM cte a
CROSS APPLY (SELECT col + ','
FROM cte B
WHERE a.col1 = b.col1
FOR XML PATH('')) cs (col)
GROUP BY col1,
LEFT(cs.col, Len(cs.col) - 1)
I think there are two problems to solve:
get the product codes for the X marks;
concatenate them into a single, comma-separated string.
I can't offer a solution for both issues in one step, but you may handle both issues separately.
1.
To replace the X marks by the respective product codes, you could use an array function to create a second table (matrix). To do so, create a new sheet, copy the first column / first row, and enter the following formula in cell B2:
=IF($B2:$E3="X";$B$1:$E$1;"")
You'll have to adapt the formula, so it covers your complete input data (If your last data cell is Z9999, it would be =IF($B2:$Z9999="X";$B$1:$Z$1;"")). My example just covers two rows and four columns.
After modifying it, confirm with CTRL+SHIFT+ENTER to apply it as array formula.
2.
Now, you'll have to concatenate the product codes. LO Calc lacks a feature to concatenate an array, but you could use a simple user-defined function. For such a string-join function, see this answer. Just create a new macro with the StarBasic code provided there and save it. Now, you have a STRJOIN() function at hand that accepts an array and concatenates its values, leaving empty values out.
You could add that function using a helper column on the second sheet and apply it by dragging it down. Finally, to get rid of the cells with the single product IDs, copy the complete second sheet, paste special into a third sheet, pasting only the values. Now, you can remove all columns except the first one (employee IDs) and the last one (with the concatenated product ids).
I created a table in sql for holding the data:
CREATE TABLE [dbo].[mydata](
[prod_code] [nvarchar](8) NULL,
[0100] [nvarchar](10) NULL,
[0101] [nvarchar](10) NULL,
[and so on...]
I created the list of columns in Calc by copying and pasting them transposed. After that I used the concatenate function to create the columnlist + datatype for the create table statement
I cleaned up the worksheet and imported it into this table using SQL Server's import wizard. Cleaning meant removing unnecessary rows/columns. Since the columnnames were identical mapping was done correctly for 99%.
Now I had the data in SQL Server.
I adapted the code MM93 suggested a bit:
;with data as
(
SELECT *
FROM dbo.mydata <-- here i simply referenced the whole table
),cte
and in the next part I uses the same 'worksheet' trick to list and format all the column names and pasted them in.
),cte
AS (SELECT prod_code, <-- had to replace col1 with 'prod_code'
col
FROM data
CROSS apply (VALUES ('0100',[0100]),
('0101', [0101] ),
(and so on... ),
The result of this query was inserted into a new table and my colleagues and I are querying our harts out :)
PS: removing the 'FOR XML' clause resulted in a table with two columns :
prodcode | employee
which containes al the unique combinations of prodcode + employeenumber which is a lot faster and much more practical to query.

SSIS: How to split excel cell value into SQL columns

I have an excel file with data like this:
ID | FieldA | FieldB
1 ABC A, B
2 FGH W, Z
3 KLÑ G, K
What I want to do is to use SSIS and import this data into a SQL Table. The only problem is that this table has an structure like this:
ID | FieldA | FieldB1 | FieldB2
So, what I need to do is to split the "FieldB" Column in Excel and put it into FieldB1 and FieldB2 in SQL.
The result would be something like this:
ID | FieldA | FieldB1 | FieldB2
1 | ABC | A | B
2 | FGH | W | Z
3 | KLÑ | G | K
Any ideas on how to achieve this?
Unless I'm missing something, I'd just skip the header row and have it import the subsequent data correctly. Take a minute or so to assign column names and voilà, done.
Try selecting the relevant range, then running this:
Sub SplitColumn()
Dim strArr() as String
Dim cell as Range
For Each cell In Selection
cell.offset(0, 1).resize(1,2).value = split(cell.value,", ")
Next cell
End Sub
Now copy and paste your data wherever required.
Non-VBA alternative:
Enter the following formula in cell D2:
=LEFT(C2,FIND(",",C2)-1)
And in E2:
=RIGHT(C2,LEN(C2)-FIND(", ",C2)-1)
And autocomplete the rest of the column.
As I see here is a detailed explanation of your example.
On the other side you can use another approach - split one excel column on two columns in excel using excel formulas and import document with 4 columns.
you can use derived column and add as two new columns .First Column expression should be like this :
SUBSTRING([FieldB],1,FINDSTRING([FieldB],",",1) - 1)
and the second one like this :
SUBSTRING([FieldB],FINDSTRING([FieldB],",",1) + 1,LEN([FieldB])- FINDSTRING([FieldB],"_",1) )

A single MySQL query for 'bouncing' table selects

So, say for the sake of simplicity, I have a master table containing two fields - The first is an attribute and the second is the attributes value. If the second field is set to reference a value in another table it is denoted in parenthesis.
Example:
MASTER_TABLE:
Attr_ID | Attr_Val
--------+-----------
1 | 23(table1) --> 23rd value from `table1`
2 | ...
1 | 42 --> the number 42
1 | 72(table2) --> 72nd value from `table2`
3 | ...
1 | txt --> string "txt"
2 | ...
4 | ...
TABLE 1:
Val_Id | Value
--------+-----------
1 | some_content
2 | ...
. | ...
. | ...
. | ...
23 | some_content
. | ...
Is it possible to perform a single query in SQL (without parsing the results inside the application and requerying the db) that would iterate trough master_table and for the given <attr_id> get only the attributes that reference other tables (e.g. 23(table1), 72(table2), ...), then parse the tables names from the parenthesis (e.g. table1, table2, ...) and perform a query to get the (23rd, 72nd, ...) value (e.g. some_content) from that referenced table?
Here is something I've done, and it parses the Attr_Val for the table name, but I don't know how to assign it to a string and then do a query with that string.
PREPARE pstmt FROM
"SELECT * FROM information_schema.tables
WHERE TABLESCHEMA = '<my_db_name>' AND TABLE_NAME=?";
SET #str_tablename =
(SELECT table.tablename FROM
(SELECT #string:=(SELECT <string_column> FROM <table> WHERE ID=<attr_id>) as String,
#loc1:=length(#string)-locate("(", reverse(#string))+2 AS from,
#loc2:=length(#string)-locate(")", reverse(#string))+1-#loc1 AS to,
substr(#string,#loc1, #loc2) AS tablename
) table
); <--this returns 1 rows which is OK
EXECUTE pstmt USING #str_tablename; <--this then returns 0 rows
Any thoughts?
I love the purity of this approach, if pulled off. But I'm thinking you're creating a maintenance bomb. With a cure like this, who needs to be sick?
No one has ever said of a web site "Man, their data sure is pure!" They compliment what is being done with the data. I don't recommend you keep your hands tied behind your back on this one. I guarantee your competitors aren't.

Resources