Power Pivot: DAX for Same Value Sequential Count - pivot-table

Please reference the following example table.
The actual table would be contained in PowerPivot.
There are multiple runs identified by sequential numbering.
Based on what we want to observe through filtering, each run has an associated value.
Here's simplified version of the current data:
Current Table
Common Columns for all Data:
Part: Uniquely defines the group. In this case, it's part or device.
Run: Identifies a same test count.
Value: The outcome generated from the test.
What I've been trying to add is an additional three columns:
Desired1: Same_Value_Count: This counts consecutive same values.
Desired2: Same_Max: Gives the maximum same value count.
Desired3: Same_Min: Give the minimum same value count.
This would result in the following PivotTable:
Resulting Table
I am having trouble formulating the proper DAX syntax to accomplish the two extra columns.
Keep in mind, I'd like to show the whole table as is.
I have a calculated column here called count_seq_dup:
=CALCULATE(COUNTROWS(table), ALLEXCEPT(table, table[3_Value]), EARLIER(Table[2_Run]) >= CSVsource[2_Run])
It worked perfectly for a single part, but does not work with multiple parts parts and when other filtering or slicers are applied.
I'm close, but it's not exactly what I'm looking for, and I can't figure out the syntax in DAX to get it right.
Can anyone help me?

For the Same_Value_Count, try something like this:
Same_Value_Count =
VAR part = 'table'[1_Part]
VAR val = 'table'[3_Value]
VAR run = 'table'[2_Run]
VAR tblpart = FILTER ( 'table', 'table'[1_Part] = part && 'table'[2_Run] <= run )
RETURN
run - CALCULATE ( MAX ( 'table'[2_Run] ), FILTER ( tblpart, [3_Value] <> val ) )
This will return the maximum same value count for a part / value combination.
Max Count =
VAR part = 'table'[1_Part]
VAR val = 'table'[3_Value]
RETURN
CALCULATE (
MAX ( 'table'[Same_Value_Count] ),
FILTER ( 'table', [3_Value] = val && 'table'[1_Part] = part )
)

Related

SQL Server - fill NULL row values with certain logic

I've got a PIVOT table output in SQL Server Management Studio. Every row contains data that are either filled or NULL. I need to fill the NULL values according to the following logic:
If value is NULL, then go further to the left (in the row) and fill it with the closest value to the left.
If there are no values to the left, then use the closest value to the right to fill it.
Thanks for your kind help,
Dave
Since you have a limited number of columns, coalesce() should do the trick
Select Product
,Time1 = coalesce(Time1,Time2,Time3,Time4,Time5,Time10,Time15,Time20,Time30)
,Time2 = coalesce(Time2,Time3,Time4,Time5,Time10,Time15,Time20,Time30,Time1)
,Time3 = coalesce(Time3,Time4,Time5,Time10,Time15,Time20,Time30,Time1,Time2)
,Time4 = coalesce(Time4,Time5,Time10,Time15,Time20,Time30,Time1,Time2,Time3)
,Time5 = coalesce(Time5,Time10,Time15,Time20,Time30,Time1,Time2,Time3,Time4)
,Time10 = coalesce(Time10,Time15,Time20,Time30,Time1,Time2,Time3,Time4,Time5)
,Time15 = coalesce(Time15,Time20,Time30,Time1,Time2,Time3,Time4,Time5,Time10)
,Time20 = coalesce(Time20,Time30,Time1,Time2,Time3,Time4,Time5,Time10,Time15)
,Time30 = coalesce(Time30,Time1,Time2,Time3,Time4,Time5,Time10,Time15,Time20)
From ...
Pivot ...

POWER BI - DAX - Measure filter

I have a dax measure . This measure have 1 data . This is "GOOGLE";"YOUTUBE";"AMAZON"
I want to use this 1 line string result in FILTER.
CALCULATE(SUM(_TABLE);_TABLE.COMPANIESNAME; FILTER(_TABLE.COMPANIESNAME IN { mymeasure } ))
Does anyone can help me solve this problem ?
Thank you for help
There are probably way better ways to do what you want. You are treating Power BI like a relational database when you should be using it like a Star Schema. But without more info, I'm just going to answer the question.
Here's my sample table:
// Table
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcsxNrMrPU9JRMlSK1YlWcs/PT89JBXKNwNzI/NKQ0iQQ3xjMd0tMTk3Kz88GCpgoxcYCAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Company = _t, Count = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Count", Int64.Type}})
in
#"Changed Type"
I don't have your DAX measure or its name, so I'm using this:
CompanyList = """Google"";""YouTube"";""Amazon"""
Just to prove it's the same as your measure, here it is in the report:
From this post I created a DAX formula that will parse your DAX value into a table with one row for each company name. Add this as a DAX table from Modeling > New Table. I named mine "Filtered table".
Filtered table = VAR CommaSeparatedList = [CompanyList]
VAR BarSeparatedList =
SUBSTITUTE ( CommaSeparatedList, ";", "|" )
VAR Length =
PATHLENGTH ( BarSeparatedList )
VAR Result =
SELECTCOLUMNS (
GENERATESERIES ( 1, Length ),
"Company", SUBSTITUTE( PATHITEM ( BarSeparatedList, [Value] ), """", "")
)
RETURN
Result
Here's what the table looks like:
Add a relationship between the two tables like this (Modeling > Manage relationships > New...):
Then add a DAX column to the filtered table by selecting the table and then Modeling > New Column
Count = CALCULATE(SUM('Table'[Count]))
You can total it up with this DAX measure:
Filtered total = SUM('Filtered table'[Count])
Change the CompanyList measure, and result will update:

Cypher statement with distinct match conditions is returning the same result

I am using Neo4j as a database to store voting information related to another database object.
I have a Vote object which has fields:
type:String with values of UP or DOWN.
argId:String which is a string ID value linking to a unique argument object
I am trying to query the number of votes assigned to a given argId using the following queries:
MATCH (v:Vote) WHERE v.argId = '214' AND v.type='DOWN'
RETURN {downvotes: COUNT(v)} AS votes
UNION
MATCH (v:Vote) WHERE v.argId = '214' AND v.type='UP'
RETURN {upvotes: COUNT(v)} AS votes
Note that this above cypher -- works and returns the expected result result like so:
[
{
"downvotes": 1
},
{
"upvotes": 10
}
]
But I feel like the query could be a bit neater and want to write something like this:
MATCH (v:Vote) WHERE v.argId = '214' AND v.type='UP'
MATCH (b:Vote) WHERE b.argId = '214' AND b.type='DOWN'
RETURN {upvotes: COUNT(v), downvotes: COUNT(b)}
Just reading it through, I think it makes sense, b and v are declared as separate variables, so all should be good (so I thought).
But running it given me this:
{
"upvotes": 10,
"downvotes": 10
}
But it should be what I have above.
Why is this?
I'm kinda new to neo4j and cypher so I've probably not understood how cypher works fully.
Can anyone shine any light?
Thank you!
p.s. I'm using Neo4j 3.5.6 and running the queries via the Desktop web browser app.
I think if you run this query you will get a clearer picture of what is happeneing. Your query produces a cartesian product of the upvotes(10) and the downvotes(1). The product is a result set of 10 rows. When they are subsequently counted, there are ten of each.
MATCH (v:Vote) WHERE v.argId = '214' AND v.type='UP'
MATCH (b:Vote) WHERE b.argId = '214' AND b.type='DOWN'
RETURN v.type, b.type
In order to get the result you want you need to filter the values and count them individually.
Rather than have two match statements, have a single match statement that retreives all of the values of interest and then use a conditional statement to filter them into upvotes and downbotes buckets.
Something like this may suit you.
MATCH (v:Vote {argId: '214'})
WHERE v.type IN ['UP', 'DOWN']
RETURN {
upvotes: count(CASE WHEN v.type = 'DOWN' THEN 1 END),
downvotes: count(CASE WHEN v.type = 'UP' THEN 1 END)
} AS vote_result
Using APOC you could do something like this whereby you use the type values themselves to aggregate the counts and then use APOC to convert it to a map with the types as the keys in the map.
MATCH (v:Vote {argId: '214'})
WHERE v.type IN ['UP', 'DOWN']
WITH [v.type, count(*)] AS vote_pair
RETURN apoc.map.fromPairs(collect(vote_pair)) AS votes

Entity Framework updates with wrong values after insert

This issue is discovered because I have an object with a field calculated off the ID, which contains the ID as part of it with a prefix and a checksum digit. It is a requirement that these calculated values are unique, but they also cannot be random, so this seemed the best way to do it.
The code in question looks like this:
entity = new Entity() { /* values */ };
context.SaveChanges(); //generate the ID field
entity.CALCULATED_FIELD = CalculateField(prefix, entity.ID);
This works just fine in 99% of cases, but occasionally we get a value in the database which looks like:
ID: 1234
CALCULATED_FIELD : prefix000{1233}8
EXPECTED: prefix000{1234}3
With the parts in the braces being calculated from the ID column.
The fact that the calculated field is incorrect is bad enough, but the implication is that upon doing a savechanges, there is no guarantee that the row returned to Entity Framework is the one which was originally worked on! I am looking into using a stored procedure on insert in order to fix the generated field problem, but in the long run we're going to have lots of bad data if we keep working on the wrong rows.
When I told entity framework to map the table to stored procedures it generated the following boilerplate code:
INSERT [dbo].[tableName](fields...)
VALUES(values...)
DECLARE #ID int
SELECT #ID = [ID]
FROM [dbo].[tableName]
WHERE ##ROWCOUNT > 0 AND [ID] = scope_identity()
SELECT t0.[ID]
FROM [dbo].[tableName] as t0
WHERE ##ROWCOUNT > 0 AND t0.[ID] = #ID
The best idea I can come up with is that an extra insert could occur before scope_identity() is called. We are migrating this system from using stored procedures where we used ##IDENTITY in place instead, could there be a difference there?
EDIT: CalculateField:
public static string CalculateField(string prefix, int ID)
{
var calculated = prefix.PadRight(17 - ID.ToString().Length)
.Replace(" ", "0") + ID.ToString();
var multiplier = 3;
var sum = 0;
foreach (char c in calculated.ToCharArray().Reverse())
{
sum += multiplier * int.Parse(c.ToString());
multiplier = 4 - multiplier;
}
if (sum % 10 == 0) { return calculated + "0"; }
return calculated + (10 - (sum % 10)).ToString();
}
UPDATE: Changing the called method from static to an instance method and only running it later after additional changed were made instead of straight after creation appears to have solved the problem, for reasons I can't comprehend. I'm leaving the question open for now since I don't yet have a large enough sample to be completely sure the problem is resolved, and also because I have no explanation for what really changed.

Filter SQL datatable according to different parameters, without a WHERE clause

I'm building an application that needs to allow the user to filter a data table according to different filters. So, the user will have three different filter posibilites but he might use only one, or two or the three of them at the same tame.
So, let's say I have the following columns on the table:
ID (int) PK
Sede (int)
Programa (int)
Estado (int)
All of those columns will store numbers, integers. The "ID" column is the primary key, "Sede" stores 1 or 2, "Programa" is any number between 1 and 15, and "Estado" will store numbers between 1 and 13.
The user may filter the data stored in the table using any of those filters (Sede, Programa or Estado). But the might, as well, use two filters, or the three of them at the same time.
The idea is that this application works like the data filters on Excel. I created a simulated table on excel to show what I want to achieve:
This first image shows the whole table, without applying any filter.
Here, the user selected a filter for "Sede" and "Programa" but leaved the "Estado" filter empty. So the query returns the values that are equal to the filter, but leaves the "Estado" filter open, and brings all the records, filering only by "Sede" (1) and "Programa" (6).
In this image, the user only selected the "Estado" filter (5), so it brings all the records that match this criteria, it doesn't matter if "Sede" or "Programa" are empty.
If I use a SELECT clasuse with a WHERE on it, it will work, but only if the three filters have a value:
DECLARE #sede int
DECLARE #programa int
DECLARE #estado int
SET #sede = '1'
SET #programa = '5'
SET #estado = '12'
SELECT * FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = #sede)
AND
([dbo].[Inscripciones].[Programa] = #programa)
AND
([dbo].[Inscripciones].[Estado] = #estado)
I also tryed changing the "AND" for a "OR", but I can't get the desired result.
Any help will be highly appreciated!! Thanks!
common problem: try using coalesce on the variable and for the 2nd value use the field name you're comparing to. Be careful though; Ensure it's NULL and not empty string being passed!
What this does is take the first non-null value of the variable passed in or the value you're comparing to.. Thus if the value passed in is null the comparison will always return true.
WHERE
[dbo].[Inscripciones].[Sede] = coalesce(#sede, [dbo].[Inscripciones].[Sede])
AND
[dbo].[Inscripciones].[Programa] = coalesce(#programa, [dbo].[Inscripciones].[Programa])
AND
[dbo].[Inscripciones].[Estado] = coalesce(#estado, [dbo].[Inscripciones].[Estado])
If sede is null and programa and estado are populated the compare would look like...
?=? (or 1=1)
?=programa variable passed in
?=Estado variable passed in
Boa Sorte!
Thank you all for your anwers. After reading the article posted in the comments by #SeanLange I was finally able to achieve what was needed. Using a CASE clause in the WHERE statement solves the deal. Here's the code:
SELECT
*
FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = (CASE WHEN #sede = '' THEN [dbo].[Inscripciones].[Sede] ELSE #sede END))
AND
([dbo].[Inscripciones].[Programa] = (CASE WHEN #programa = '' THEN [dbo].[Inscripciones].[Programa] ELSE #programa END))
AND
([dbo].[Inscripciones].[Estado] = (CASE WHEN #estado = '' THEN [dbo].[Inscripciones].[Estado] ELSE #estado END))
AND
([dbo].[Inscripciones].[TipoIngreso] = (CASE WHEN #tipoingreso = '' THEN [dbo].[Inscripciones].[TipoIngreso] ELSE #tipoingreso END))
Thanks again!!

Resources