I'm brand new in Cube world and I need to do a query extending some values form dimensions.
For example:
Having dimension [time].[Numeric Month], with values [time].[Numeric Month].&[1]..[time].[Numeric Month].&[12]
What i need is group that values like this
[time].[Numeric Month].&[1]...[time].[Numeric Month].&[4] = A
[time].[Numeric Month].&[5]...[time].[Numeric Month].&[12] = B
(is an example)
and perform a query wich result show be like this on Rows
A
|->1
|->2
|->3
|->4
B
|->5
|->6
|->7
|->8
|->9
|->10
|->11
|->12
I could do the grouping but when I tried to use the same hierarchy used for the grouping as another level of row I've an error(it make sense) of hierarchy is used more than once
It's possible to do this kind of query?
This is the MDX:
WITH
MEMBER [Tiempo].[Mes Numerico].[A] AS
[Tiempo].[Mes Numerico].&[1]
MEMBER [Tiempo].[Mes Numerico].[A ] AS
Aggregate
(
{
[Tiempo].[Mes Numerico].&[1]
,[Tiempo].[Mes Numerico].&[2]
,[Tiempo].[Mes Numerico].&[3]
}
)
MEMBER [Tiempo].[Mes Numerico].[D ] AS
Aggregate
(
{
[Tiempo].[Mes Numerico].&[10]
,[Tiempo].[Mes Numerico].&[11]
,[Tiempo].[Mes Numerico].&[12]
}
)
MEMBER [Measures].[Proyectos Tiempos-Horas40538889] AS
[Measures].[Proyectos Tiempos-Horas]
SELECT
NON EMPTY
(
[Tiempo].[Mes Numerico]
,
{
[Tiempo].[Mes Numerico].[A ]
,[Tiempo].[Mes Numerico].[D ]
}
*
{[Measures].[Proyectos Tiempos-Horas40538889]}
) ON COLUMNS
FROM [VisionarisDW];
Probably something like this should work:
WITH
MEMBER [Tiempo].[Mes Numerico].[A] AS
AGGREGATE
(
{
[Tiempo].[Mes Numerico].&[1]
,[Tiempo].[Mes Numerico].&[2]
,[Tiempo].[Mes Numerico].&[3]
}
, [Measures].[Proyectos Tiempos-Horas]
)
MEMBER [Tiempo].[Mes Numerico].[B] AS
AGGREGATE
(
{
[Tiempo].[Mes Numerico].&[4]
,[Tiempo].[Mes Numerico].&[5]
,[Tiempo].[Mes Numerico].&[6]
}
, [Measures].[Proyectos Tiempos-Horas]
)
MEMBER [Measures].[Proyectos Tiempos-Horas40538889] AS
[Measures].[Proyectos Tiempos-Horas]
SELECT
NON EMPTY [Measures].[Proyectos Tiempos-Horas40538889] ON COLUMNS,
{
[Tiempo].[Mes Numerico].&[1],
[Tiempo].[Mes Numerico].&[2],
[Tiempo].[Mes Numerico].&[3],
[Tiempo].[Mes Numerico].[A],
[Tiempo].[Mes Numerico].&[4],
[Tiempo].[Mes Numerico].&[5],
[Tiempo].[Mes Numerico].&[6],
[Tiempo].[Mes Numerico].[B]
} ON ROWS
FROM [VisionarisDW];
Related
I have a JSON structure in a field that looks like this. I'm trying to extract every task in every category, there could be any number of tasks or categories.
I've got part of the way there by extracting a single category, but can't seem to do it for every task in every category.
"tasks": {
"category-business": [
{
"dateCompleted": {
"_seconds": 1653672655,
"_nanoseconds": 791000000
},
"slug": "task-alpha",
"status": "completed"
},
{
"dateCompleted": {
"_seconds": 1654516259,
"_nanoseconds": 796000000
},
"slug": "task-bravo",
"status": "completed"
}
],"category-community": [
{
"dateCompleted": {
"_seconds": 1654709063,
"_nanoseconds": 474000000
},
"slug": "task-papa",
"status": "completed"
},
{
"dateCompleted": {
"_seconds": 1654709841,
"_nanoseconds": 764000000
},
"slug": "task-zebra",
"status": "completed"
}
]}
Here's the query so far
SELECT
*
FROM
(
SELECT
ARRAY(
SELECT
STRUCT(
TIMESTAMP_SECONDS(
CAST(
JSON_EXTRACT_SCALAR(business_tasks, '$.dateCompleted._seconds') AS INT64
)
) AS dateCompleted,
json_extract_scalar(business_tasks, '$.slug') AS task_slug,
json_extract_scalar(business_tasks, '$.status') AS status
)
FROM
UNNEST(
json_extract_array(DATA, '$.tasks.category-business')
) business_tasks
) AS items
FROM
`table`
)
This extracts just the information in the category business.
What I'm trying to do is expand category-community and any other children underneath the tasks key. The real data has at least 10 categories and 50 tasks.
I think I need to do another round of UNNEST and json_extract_array but I can't quite work out the correct order?
Consider below approach
create temp function get_keys(input string) returns array<string> language js as """
return Object.keys(JSON.parse(input));
""";
create temp function get_values(input string) returns array<string> language js as """
return Object.values(JSON.parse(input));
""";
create temp function get_leaves(input string) returns string language js as '''
function flattenObj(obj, parent = '', res = {}){
for(let key in obj){
let propName = parent ? parent + '.' + key : key;
if(typeof obj[key] == 'object'){
flattenObj(obj[key], propName, res);
} else {
res[propName] = obj[key];
}
}
return JSON.stringify(res);
}
return flattenObj(JSON.parse(input));
''';
create temp table temp_table as (
select
split(key, '.')[offset(0)] as category,
split(key, '.')[offset(1)] as offset,
split(key, '.')[offset(2)] || ifnull(split(key, '.')[safe_offset(3)], '') as key,
val, format('%t', t) row_id
from your_table t, unnest([struct(get_leaves(json_extract(data, '$.tasks')) as leaves)]),
unnest(get_keys(leaves)) key with offset
join unnest(get_values(leaves)) val with offset using(offset)
);
execute immediate (
select '''
select * except(row_id) from temp_table
pivot (any_value(val) for key in ("''' || keys || '"))'
from (
select string_agg(key, '","') keys
from (select distinct key from temp_table)
)
);
if applied to sample data in your question - output is
DML only:
with category_level as (
select
coalesce(
json_query_array(DATA.tasks[a], '$.category-business')
, json_query_array(DATA.tasks[a], '$.category-community')
, json_query_array(DATA.tasks[a], '$.category-3')
, json_query_array(DATA.tasks[a], '$.category-4')
, json_query_array(DATA.tasks[a], '$.category-5')
, json_query_array(DATA.tasks[a], '$.category-6')
, json_query_array(DATA.tasks[a], '$.category-7')
, json_query_array(DATA.tasks[a], '$.category-8')
, json_query_array(DATA.tasks[a], '$.category-9')
, json_query_array(DATA.tasks[a], '$.category-10')
) category_array
from table
left join unnest(generate_array(0, 100)) a
where DATA.tasks[a] is not null
)
select
timestamp_seconds(cast(json_extract_scalar(b.dateCompleted._seconds) as int64)) dateCompleted
, json_extract_scalar(b.slug) slug
, json_extract_scalar(b.status) status
from category_level
left join unnest(category_array) b
https://console.cloud.google.com/bigquery?sq=1013309549723:fe8b75122e5b4b549e8081df99584c81
new version:
select
timestamp_seconds(cast(regexp_extract_all(to_json_string(json_extract(DATA,'$.tasks')), r'"_seconds":(\d*)')[offset(a)] as int64)) dateCompleted
, regexp_extract_all(to_json_string(json_extract(DATA,'$.tasks')), r'"slug":"([a-z\-]*)"')[offset(a)] task_slug
, regexp_extract_all(to_json_string(json_extract(DATA,'$.tasks')), r'"status":"([a-z\-]*)"')[offset(a)] status
from table
join unnest(generate_array(0,-1+array_length(regexp_extract_all(to_json_string(json_extract(DATA,'$.tasks')), r'"slug":"([a-z\-]*)"')))) a
https://console.cloud.google.com/bigquery?sq=1013309549723:9f43bd653ba14589b31a1f5673adcda7
Is that possible create a multi-level json string in SQL Server 2016 ? I have a table (patient_data) like this:
And what i want to do is to create json string output in SQL Server like this:
{
"patient":[
{
"key":"A",
"data":[
{
"name":"Amy Farha",
"colored":"darkred",
"avatar_url":"https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg",
"subtitle":"Vice President",
"patientid":"qweqweqeqeq"
},
{
"name":"Anies",
"colored":"darkblue",
"avatar_url":"https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg",
"subtitle":"Vice Chairman",
"patientid":"avasdasdad"
}
]
},
{
"key":"B",
"data":[
{
"name":"Bryan Adams",
"colored":"darkgreen",
"avatar_url":"https://randomuser.me/api/portraits/med/women/91.jpg",
"subtitle":"Reggae Man",
"patientid":"avasdasdad"
}
]
},
{
"key":"D",
"data":[
{
"name":"David dummy",
"colored":"darkgreen",
"avatar_url":"https://randomuser.me/api/portraits/med/women/91.jpg",
"subtitle":"Reggae Man",
"patientid":"avasdasdad"
}
]
},
{
"key":"M",
"data":[
{
"name":"Muhammad Adams",
"colored":"darkgreen",
"avatar_url":"https://randomuser.me/api/portraits/med/women/91.jpg",
"subtitle":"Reggae Man",
"patientid":"avasdasdad"
}
]
},
{
"key":"T",
"data":[
{
"name":"Tere",
"colored":"darkgreen",
"avatar_url":"https://randomuser.me/api/portraits/med/women/91.jpg",
"subtitle":"Reggae Man",
"patientid":"avasdasdad"
},
{
"name":"Tifanny",
"colored":"darkblue",
"avatar_url":"https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg",
"subtitle":"Vice Chairman",
"patientid":"avasdasdad"
}
]
},
{
"key":"X",
"data":[
{
"name":"Xavier",
"colored":"darkgreen",
"avatar_url":"https://randomuser.me/api/portraits/med/women/91.jpg",
"subtitle":"Reggae Man",
"patientid":"avasdasdad"
}
]
}
]
}
**NOTE "key" is a grouping by the first letter of patient's name
I try use json path but couldn't figure out in multi level case .I hope someone can help me
Try the following queries with FOR JSON PATH
-- test data
CREATE TABLE Patients(
id int,
name varchar(100)
)
INSERT Patients(id,name)VALUES
(11,'A Patient 11'),(12,'A Patient 12'),
(21,'B Patient 21'),
(31,'C Patient 31'),(32,'C Patient 32')
-- query 1
SELECT
(
SELECT
k.[key],
(SELECT p.id,p.[name] FROM Patients p WHERE LEFT(p.[name],1)=k.[key] FOR JSON PATH) [data]
FROM
(
SELECT DISTINCT LEFT([name],1) [key]
FROM Patients
) k
ORDER BY k.[key]
FOR JSON PATH
) patient
FOR JSON PATH
/*
[
{"patient":[
{"key":"A","data":[{"id":11,"name":"A Patient 11"},{"id":12,"name":"A Patient 12"}]},
{"key":"B","data":[{"id":21,"name":"B Patient 21"}]},
{"key":"C","data":[{"id":31,"name":"C Patient 31"},{"id":32,"name":"C Patient 32"}]}
]
}
]
*/
-- query 2
SELECT
k.[key] [patient.key],
(SELECT p.id,p.[name] FROM Patients p WHERE LEFT(p.[name],1)=k.[key] FOR JSON PATH) [patient.data]
FROM
(
SELECT DISTINCT LEFT([name],1) [key]
FROM Patients
) k
ORDER BY k.[key]
FOR JSON PATH
/*
[
{"patient":{"key":"A","data":[{"id":11,"name":"A Patient 11"},{"id":12,"name":"A Patient 12"}]}},
{"patient":{"key":"B","data":[{"id":21,"name":"B Patient 21"}]}},
{"patient":{"key":"C","data":[{"id":31,"name":"C Patient 31"},{"id":32,"name":"C Patient 32"}]}}
]
*/
You can append WITHOUT_ARRAY_WRAPPER to remove the brackets [ and ]
SELECT
(
SELECT
k.[key],
(SELECT p.id,p.[name] FROM Patients p WHERE LEFT(p.[name],1)=k.[key] FOR JSON PATH) [data]
FROM
(
SELECT DISTINCT LEFT([name],1) [key]
FROM Patients
) k
ORDER BY k.[key]
FOR JSON PATH
) patient
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
/*
{
"patient":[
{"key":"A","data":[{"id":11,"name":"A Patient 11"},{"id":12,"name":"A Patient 12"}]},
{"key":"B","data":[{"id":21,"name":"B Patient 21"}]},
{"key":"C","data":[{"id":31,"name":"C Patient 31"},{"id":32,"name":"C Patient 32"}]}
]
}
*/
I found another more shorter variant. You can use ROOT('patient') option here
SELECT
k.[key] [key],
(SELECT p.id,p.[name] FROM Patients p WHERE LEFT(p.[name],1)=k.[key] FOR JSON PATH) [data]
FROM
(
SELECT DISTINCT LEFT([name],1) [key]
FROM Patients
) k
ORDER BY k.[key]
FOR JSON PATH, ROOT('patient')
/*
{
"patient":[
{"key":"A","data":[{"id":11,"name":"A Patient 11"},{"id":12,"name":"A Patient 12"}]},
{"key":"B","data":[{"id":21,"name":"B Patient 21"}]},
{"key":"C","data":[{"id":31,"name":"C Patient 31"},{"id":32,"name":"C Patient 32"}]}
]
}
*/
Morning,
I have the following MDX and would like to place a filter on the measure 'Estimated Unbilled Outstanding Subtotal £'. I have searched through the forums and understand that I should be able to use FILTER or WHERE, but I cannot adapt the examples to work for me. Would really appreciate any assistance.
SELECT
{ [Measures].[Estimated Unbilled Outstanding Subtotal £] } ON COLUMNS
,{ NONEMPTY(
{ [Customer].[Billing Team].[All].CHILDREN }
* { [Customer].[Customer Name].[All].CHILDREN }
* { [Account].[Account ID].[All].CHILDREN }
* { [Account].[Account Type].&[Import]
, [Account].[Account Type].&[Other Non Billable] }
, { [Measures].[Estimated Unbilled Outstanding Subtotal £] }
) } ON ROWS
FROM [BDW];
Many thanks
Adrian
You need to put a filter around the ROWS clause:
SELECT
{ [Measures].[Estimated Unbilled Outstanding Subtotal £] } ON COLUMNS
,
FILTER(
NONEMPTY(
{ [Customer].[Billing Team].[All].CHILDREN }
* { [Customer].[Customer Name].[All].CHILDREN }
* { [Account].[Account ID].[All].CHILDREN }
* { [Account].[Account Type].&[Import]
, [Account].[Account Type].&[Other Non Billable] }
, { [Measures].[Estimated Unbilled Outstanding Subtotal £] }
)
,[Measures].[Estimated Unbilled Outstanding Subtotal £] >1000
)
ON ROWS
FROM [BDW];
In this query i used were clause in that year is 2015 and quarter-[2013]&[Quarter1], how is it possible, and getting result set 10 records. actually result set is not displaying.
WITH MEMBER [Measures].[Test] AS ( [Measures].[ProgramAssessmentPatientCnt] + [Measures].[AssessmentPatientCnt] )
MEMBER [Measures].[Test1] AS ( [Measures].[CCMPatientCnt] + [Measures].[CareteamCnt] + [Measures].[CCMPatientCnt] )
SELECT ( ( { [DimEnrollStatus].[EnrollmentStatus].[EnrollmentStatus] } ),
{ [Measures].[AssessmentPatientCnt], [Measures].[Test], [Measures].[Test1] } ) ON COLUMNS,
Subset (
NonEmpty (
{
( { [DimAssessment].[AssessmentText].[AssessmentText] },
{ [DimAssessment].[QuestionText].[QuestionText] },
{ [DimAssessment].[AnswerText].[AnswerText] } )
},
{ [Measures].[AssessmentPatientCnt], [Measures].[Test], [Measures].[Test1] }
),
0,
10
) ON ROWS
FROM [NavigateCube]
WHERE (
{
( { [DimManagedPopulation].[ManagedPopulationName].&[1044]&[LTC Lincoln Centers] },
{ [DimAnchorDate].[Calender Year].&[2015] },
{ [DimAnchorDate].[Calendar Semester Des].[All] },
{ [DimAnchorDate].[Calendar Quarter Des].&[2013]&[Quarter1] },
{ [DimAnchorDate].[English Month Name Desc].[All] } )
} )
Does this return any rows?
WHERE
(
[DimManagedPopulation].[ManagedPopulationName].&[1044]&[LTC Lincoln Centers],
[DimAnchorDate].[Calender Year].&[2015],
//[DimAnchorDate].[Calendar Semester Des].[All],
[DimAnchorDate].[Calendar Quarter Des].&[2013]&[Quarter1],
[DimAnchorDate].[English Month Name Desc].[All]
);
Maybe the following:
WHERE
(
[DimManagedPopulation].[ManagedPopulationName].&[1044]&[LTC Lincoln Centers],
{
[DimAnchorDate].[Calender Year].&[2015],
[DimAnchorDate].[Calendar Semester Des].[All],
[DimAnchorDate].[Calendar Quarter Des].&[2013]&[Quarter1],
[DimAnchorDate].[English Month Name Desc].[All]
}
);
For displaying the result set, it takes 2 minutes. Is there any way to optimise the query?
WITH MEMBER [Measures].[TestMeasure] AS
(
[Measures].[EnrollPatientCnt]
+ [Measures].[AssessmentPatientCnt]
+ [Measures].[ProgramAssessmentPatientCnt]
)
MEMBER [Measures].[TotalCount] AS
Count(
NonEmpty(
(
{ [DimAssessment].[AssessmentText].[AssessmentText] },
{ [DimAssessment].[QuestionText].[QuestionText] },
{ [DimAssessment].[AnswerText].[AnswerText] }
)
,{
[Measures].[AssessmentPatientCnt]
, [Measures].[TestMeasure]
}
) )
SELECT
NON EMPTY [Measures].[TotalCount] ON COLUMNS
FROM [NavigateCube]
WHERE
(
{
(
{
[DimManagedPopulation].[ManagedPopulationName].&[1034]&[TC Tammy Brown Care Team]
}
)
}
);
Basically the same approach as Greg/Mosha:
WITH
MEMBER [Measures].[TestMeasure] AS
[Measures].[EnrollPatientCnt]
+ [Measures].[AssessmentPatientCnt]
+ [Measures].[ProgramAssessmentPatientCnt]
MEMBER [Measures].[MeasureIsEmpty] AS
IIF(
NOT ISEMPTY([Measures].[TestMeasure])
OR NOT ISEMPTY([Measures].[AssessmentPatientCnt])
,1
,NULL
)
MEMBER [Measures].[TotalCount] AS
SUM(
[DimAssessment].[AssessmentText].[AssessmentText]
*[DimAssessment].[QuestionText].[QuestionText]
*[DimAssessment].[AnswerText].[AnswerText]
,[Measures].[MeasureIsEmpty]
)
SELECT
NON EMPTY [Measures].[TotalCount] ON 0
FROM [NavigateCube]
WHERE [DimManagedPopulation].[ManagedPopulationName].&[1034]&[TC Tammy Brown Care Team];
How does this query perform?
WITH MEMBER [Measures].[TestMeasure] AS
IIf(
Not(IsEmpty([Measures].[EnrollPatientCnt]))
or Not(IsEmpty([Measures].[AssessmentPatientCnt]))
or Not(IsEmpty([Measures].[ProgramAssessmentPatientCnt]))
,1
,Null
)
MEMBER [Measures].[TotalCount] AS
Sum (
( { [DimAssessment].[AssessmentText].[AssessmentText] },
{ [DimAssessment].[QuestionText].[QuestionText] },
{ [DimAssessment].[AnswerText].[AnswerText] } ),
[Measures].[TestMeasure]
)
SELECT NON EMPTY [Measures].[TotalCount] ON COLUMNS
FROM [NavigateCube]
WHERE (
{
( { [DimManagedPopulation].[ManagedPopulationName].&[1034]&[TC Tammy Brown Care Team] } )
} )
It's not identical, but it's a similar concept to what Mosha blogged about here.