Simple Having Clause created with Power BI measure - sql

I created this simple table in SQL:
create table testTable (
date date not null,
leader varchar(20),
name varchar(20)
)
insert into testTable
values
('2021-01-01', 'KIM', 'Anders'),
('2021-01-02', 'KIM', 'Annika'),
('2021-01-03', 'KIM', 'Anna'),
('2021-01-04', 'KIM', 'Anna'),
('2021-01-03', 'KIM', 'Annika'),
('2021-01-01', 'JOHAN', 'Sara'),
('2021-01-02', 'JOHAN', 'Sara'),
('2021-01-03', 'JOHAN', 'Sara')
I am trying to get an ekvivalent solution to the following code in a dax measure if possible
select max(leader), name, count(name)
from testTable
group by name
having count(name) >= 2
The result that im looking for is.
Leader
Measure
KIM
2
JOHAN
1

Think about HAVING as a filter that happens after a grouping. So something like
Measure = COUNTROWS(filter(SUMMARIZECOLUMNS('Table'[Name],"Count",count('Table'[Name])), [Count]>=2))
And here's a simple way to present test data for DAX questions, entirely in DAX:
testTable = SELECTCOLUMNS
(
{
(date(2021,01,01),"KIM","Anders")
,(date(2021,01,02),"KIM","Annika")
,(date(2021,01,03),"KIM","Anna")
,(date(2021,01,04),"KIM","Anna")
,(date(2021,01,03),"KIM","Annika")
,(date(2021,01,01),"JOHAN","Sara")
,(date(2021,01,02),"JOHAN","Sara")
,(date(2021,01,03),"JOHAN","Sara")
}, "date", [Value1]
, "leader", [Value2]
, "name", [Value3]
)
This is much easier way to reproduce a scenario than creating a table in SQL Server, and loading it through Power Query, or using the "Enter Data" form in PowerBI which creates the table in Power Query.

Edit: after adding the desired result to the question, the answer changes like follows
A possible solution is to implement a measure that counts the number of names that appear more than once for the selected leader
# Names ge 2 =
COUNTROWS (
FILTER (
VALUES ( Test[name] ),
CALCULATE ( COUNTROWS ( Test ), ALLEXCEPT ( Test, Test[name], Test[leader] ) ) > 1
)
)
here is a working example on dax.do
DEFINE
TABLE Test =
DATATABLE (
"date", DATETIME,
"leader", STRING,
"name", STRING,
{
{ "2021-01-01", "KIM", "Anders" },
{ "2021-01-02", "KIM", "Annika" },
{ "2021-01-03", "KIM", "Anna" },
{ "2021-01-04", "KIM", "Anna" },
{ "2021-01-03", "KIM", "Annika" },
{ "2021-01-01", "JOHAN", "Sara" },
{ "2021-01-02", "JOHAN", "Sara" },
{ "2021-01-03", "JOHAN", "Sara" }
}
)
MEASURE Test[# Names ge 2] =
COUNTROWS (
FILTER (
VALUES ( Test[name] ),
CALCULATE ( COUNTROWS ( Test ), ALLEXCEPT ( Test, Test[name], Test[leader] ) ) > 1
)
)
EVALUATE
SUMMARIZECOLUMNS (
Test[leader],
"# Names ge 2", [# Names ge 2]
)
and the resulting output
I've left the measure of my previous answer on the original dax.do, that returned this output

Related

Query key values in a json column

I have a table "jobs" with one of the columns called "check_list" ( varchar(max) that has JSON values, an example value would be
{
"items":[
{
"name":"machine 1",
"state":"",
"comment":"",
"isReleaseToProductionCheck":true,
"mnachine_id":10
},
{
"name":"machine 2",
"state":"",
"comment":"",
"isReleaseToProductionCheck":true,
"machine_id":12
}
]
}
Now how would I write a SQL query to only return the rows where the column "check_list" has items[machine_id] = 12
In the end after some trial and error this was the solution that worked for me. I had to add the ISJSON check because some of the older data was invalid
WITH jobs (id, workorder, selectedMachine) AS(
SELECT
[id],
[workorder],
(
select
*
from
openjson(check_list, '$.items') with (machine_id int '$.machine_id')
where
machine_id = 12
) as selectedMachine
FROM
engineering_job_schedule
WHERE
ISJSON(check_list) > 0
)
Select
*
from
jobs
where
selectedMachine = 12

BigQuery JSON EXTRACT

[
{
"key":"expiry_date",
"type":"date",
"label":"Expiry Date",
"required":false,
"default_value":"2029-12-15"
},
{
"key":"brand",
"type":"text",
"label":"Brand",
"required":false,
"default_value":"clipsal"
}
]
Is there a way that I could extract the default_value of "expiry_date" in the nested JSON above? The data is under a column called attributes.
Have you tried any of these functions described here? Maybe it can help.
Also, if the first element of the json array will be always what you want, you could use something like:
WITH test_table AS (
SELECT "[{\"key\":\"expiry_date\",\"type\":\"date\",\"label\":\"Expiry Date\",\"required\":false,\"default_value\":\"2029-12-15\"},{\"key\":\"brand\",\"type\":\"text\",\"label\":\"Brand\",\"required\":false,\"default_value\":\"clipsal\"}]" AS json_text_field
)
SELECT JSON_EXTRACT(json_text_field, '$[0].default_value') FROM test_table
If the keys it's not always the first, you could use this instead:
WITH test_table AS (
SELECT "[{\"key\":\"expiry_date\",\"type\":\"date\",\"label\":\"Expiry Date\",\"required\":false,\"default_value\":\"2029-12-15\"},{\"key\":\"brand\",\"type\":\"text\",\"label\":\"Brand\",\"required\":false,\"default_value\":\"clipsal\"}]" AS json_text_field
)
SELECT value FROM (
SELECT JSON_EXTRACT(json_text_field, '$.key') AS id, JSON_EXTRACT(json_text_field, '$.default_value') AS value FROM test_table, UNNEST(JSON_EXTRACT_ARRAY(json_text_field, '$')) AS json_value
) WHERE id = '"expiry_date"'
Below is for BigQuery Standard SQL
#standardSQL
SELECT JSON_EXTRACT_SCALAR(el, '$.default_value') AS default_value
FROM `project.dataset.table`,
UNNEST(JSON_EXTRACT_ARRAY(json)) el
WHERE JSON_EXTRACT_SCALAR(el, '$.key') = 'expiry_date'
You can test above with sample / dummy data from y our question as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT '''
[
{
"key":"expiry_date",
"type":"date",
"label":"Expiry Date",
"required":false,
"default_value":"2029-12-15"
},
{
"key":"brand",
"type":"text",
"label":"Brand",
"required":false,
"default_value":"clipsal"
}
]
''' json
)
SELECT JSON_EXTRACT_SCALAR(el, '$.default_value') AS default_value
FROM `project.dataset.table`,
UNNEST(JSON_EXTRACT_ARRAY(json)) el
WHERE JSON_EXTRACT_SCALAR(el, '$.key') = 'expiry_date'
with output
Row default_value
1 2029-12-15
Depends on your real use case - you can consider below variation
#standardSQL
SELECT *,
(
SELECT JSON_EXTRACT_SCALAR(el, '$.default_value')
FROM UNNEST(JSON_EXTRACT_ARRAY(json)) el
WHERE JSON_EXTRACT_SCALAR(el, '$.key') = 'expiry_date'
) AS default_value
FROM `project.dataset.table`

How to set more than a filter over JSON data using JSON_VALUE?

I'm just trying to set a query to get data from a collection of object JSON:
create table test (LINE_SPECS nvarchar(max));
insert into test values (N'
{
"lineName":"GHjr",
"pipeDiameter":"12",
"pipeLength":"52000",
"pressure":"15",
"volume":"107"
},
{
"lineName":"Ks3R",
"pipeDiameter":"9",
"pipeLength":"40000",
"pressure":"15",
"volume":"80"
}
');
Now, as getting lineName of the first object ( lineName : Ghjr) is a success
select
JSON_VALUE(LINE_SPECS, '$.lineName') as line_name
, JSON_VALUE(LINE_SPECS, '$.pipeDiameter') as diameter
from test
WHERE JSON_VALUE(LINE_SPECS, '$.lineName') = 'GHjr'
;
that is not possible when I try to get the second that is "Ks3R" :
select
JSON_VALUE(LINE_SPECS, '$.lineName') as line_name
, JSON_VALUE(LINE_SPECS, '$.pipeDiameter') as diameter
from test
WHERE JSON_VALUE(LINE_SPECS, '$.lineName') = 'Ks3R'
How can I do that ?
Thanks.
First your JSON data isn't valid, it might be an array.
look like this.
create table test (LINE_SPECS nvarchar(max));
insert into test values (N'
[
{
"lineName":"GHjr",
"pipeDiameter":"12",
"pipeLength":"52000",
"pressure":"15",
"volume":"107"
},
{
"lineName":"Ks3R",
"pipeDiameter":"9",
"pipeLength":"40000",
"pressure":"15",
"volume":"80"
}
]');
You can try to use OPENJSON with CROSS APPLY to parse JSON and make it.
select
t2.*
from test t1
CROSS APPLY
OPENJSON(t1.LINE_SPECS)
WITH
(
line_name varchar(MAX) N'$.lineName',
diameter varchar(MAX) N'$.pipeDiameter'
) AS t2
WHERE line_name = 'Ks3R'
sqlfiddle

MDX - multiple filters on different dimension with OR condition

I have a problem with MDX querying.
I have one measure WEIGHT and two dimensions DESTINATION and SOURCE with the same attributes: NAME and TYPE.
I want to return:
SUM of WEIGHT
where
DESTINATION.TYPE="A"
**OR**
SOURCE.TYPE="B"
**AND**
(DESTINATION.TYPE **<>** SOURCE.TYPE)
If try this:
SELECT NON EMPTY {
[Measures].[Weight]
}
ON COLUMNS,
NON EMPTY {
([Source].[Name].[Name].ALLMEMBERS * [Destination].[Name].[Name].ALLMEMBERS )
}
ON ROWS
FROM
( SELECT ( { [Source].[Type].&[A] } ) ON COLUMNS FROM ( SELECT ( { [Destination].[Type].&[B] } )
ON COLUMNS FROM [CUBE])) WHERE ( [Destination].[Type].&[B], [Source].[Type].&[A] )
But it doesn't work.
In SQL it look like
Select source.name, destination.name, sum(weight) from cube
where
(source.type = "A" or destination.type = "b")
and
(source.type <> destination.type)
group by source.name, destination.name, source.type, destination.type
Your From section is a bit messy. Try the following:
SELECT
NON EMPTY { [Measures].[Weight] } ON COLUMNS,
NON EMPTY { [Source].[Name].[Name].ALLMEMBERS * [Destination].[Name].[Name].ALLMEMBERS } ON ROWS
FROM [CUBE]
WHERE ( {[Destination].[Type].&[B]} * {[Source].[Type].[All]} + {[Destination].[Type].[All]} * {[Source].[Type].&[A]} )

How do you get the total rows in an MDX query to use for paging?

I am attempting to implement paging to large datasets in MDX (SSAS).
I have the following to retrieve paged data which works fine:
SELECT
{
[Measures].[Mesasure1],
[Measures].[Measure2]
} ON COLUMNS,
SUBSET
(
ORDER
(
{
(
[Item].[Category].ALLMEMBERS
)
}, NULL, BASC
), 10, 50 --10 = start index, 50 = returned roes
)
ON ROWS
FROM ( SELECT ( { [Time].[Date].&[2012-04-15T00:00:00]:[Time].[Date].&[2012-04-20T00:00:00] } ) ON COLUMNS
FROM [DataMartPerformance]
))
However I cannot for the life of me find anywhere on the internet that helps explain how to get the total rows available. Do I do it in a seperate query? If so how?
Or can I wrap it into this one query somehow?
Similar to how you'd do TSQL paging, you'll need to run another query to count the total elements. You may have to tinker with this depending on how you've done your original query, but I use something like:
WITH
MEMBER [Measures].[ElementCount] AS
{
NONEMPTY
(
{
[Item].[Category].ALLMEMBERS *
{ [Time].[Date].&[2012-04-15T00:00:00]:[Time].[Date].&[2012-04-20T00:00:00] }
},
{
[Measures].[Mesasure1],
[Measures].[Measure2]
}
)
}.COUNT
SELECT
{
[Measures].[ElementCount]
}
ON COLUMNS
FROM
[DataMartPerformance]
For filtering, you can do dimension filters by using an exists against your dimension attributes:
WITH
MEMBER [Measures].[ElementCount] AS
{
NONEMPTY
(
EXISTS
(
{
[Item].[Category].ALLMEMBERS *
{ [Time].[Date].&[2012-04-15T00:00:00]:[Time].[Date].&[2012-04-20T00:00:00] }
},
{
[Dimension].[Attribute].[FilterByThisAttribute]
}
),
{
[Measures].[Mesasure1],
[Measures].[Measure2]
}
)
}.COUNT
SELECT
{
[Measures].[ElementCount]
}
ON COLUMNS
FROM
[DataMartPerformance]
I haven't got to writing the measure value filters yet, I need to do that next for my own MDX paging constructor...
Please try this:
WITH
SET MySet As
(
NONEMPTY (
[AU Time Sale Hour].[Hour Key].[Hour Key]
* [Dim Country].[Country Key].[Country Key]
)
)
Member [Measures] .cnt AS MySet.Count
select [Measures] .cnt on Columns
from [Me Stats DW Fact Sales]
where (
{[Dim Visa].[Visa Key].&[2067],[Dim Visa].[Visa Key].&[2068] },
[AU Time Sale Date].[Date].&[20091120]:[AU Time Sale Date].[Date].&[20091125]
)