I have a JSON value for a column which is array of objects. Here, my requirement is to find the count of objects matching the filter
Row 1: Coumn 1
{
"createdBy": 2,
"teams": [
{
"companyId" : 1,
"teamId": 1
},
{
"companyId" : 1,
"teamId": 2
}
]
}
Row 2: Coumn 1
{
"createdBy": 2,
"teams": [
{
"companyId" : 1,
"teamId": 3
},
{
"companyId" : 1,
"teamId": 4
}
]
}
Here, companyId 1 presents in 4 places and i need the query to get the count.
Query tried,
select count(1) from a where any_match(
split(
trim(
'[]'
FROM
json_query(
a.teams,
'lax $.companyId' WITH ARRAY WRAPPER
)
),
',"'
),
x -> trim(
'"'
FROM
x
) = 2
)
Here it returns 1 because of any_match. Not sure how to get the size.
Related
The query statement which need to be executed is
dslContext.select(
jsonObject(
key("id").value(ENTITY.ID),
key("name").value(ENTITY.NAME),
key("attributes").value(
coalesce(
select(
jsonArrayAgg(
jsonObject(
key("id").value(ATTRIBUTE.ID),
key("name").value(ATTRIBUTE.NAME),
key("indexValue").value(ATTRIBUTE.INDEX_VALUE)
)
)
).from(ATTRIBUTE)
.where(ATTRIBUTE.ENTITY_ID.eq(ENTITY.ID))
.orderBy(ATTRIBUTE.INDEX_VALUE.asc()),
jsonArray()
)
)
)
).from(ENTITY).fetchInto(EntityDto.class)
Response for the above query:
[
{
"id": 2,
"name": "Address",
"attributes": [
{
"id": 3,
"name": "Pincode",
"indexValue": 4
},
{
"id": 4,
"name": "Country",
"indexValue": 3
},
{
"id": 5,
"name": "City",
"indexValue": 2
},
{
"id": 6,
"name": "Address",
"indexValue": 1
}
]
}
]
The attributes are not sorting in ascending order with respect to indexValue.
How to make the attributes sort in the ascending order?
Use the ORDER BY clause on JSON_ARRAYAGG:
jsonArrayAgg(...).orderBy(...)
Query:
SELECT value FROM test.json_test FORMAT JSON
Response:
{
"meta":
[
{
"name": "value",
"type": "Int32"
}
],
"data":
[
{
"value": 1
}
],
"rows": 1,
"statistics":
{
"elapsed": 0.112135109,
"rows_read": 1,
"bytes_read": 4
}
}
How to exclude unnecessary fields and leave only data field?
You can exclude "statistics" from output:
set output_format_write_statistics=0;
ubuntu-16gb-nbg1-1 :) select 1 format JSON;
SELECT 1
FORMAT JSON
{
"meta":
[
{
"name": "1",
"type": "UInt8"
}
],
"data":
[
{
"1": 1
}
],
"rows": 1
}
1 rows in set. Elapsed: 0.003 sec.
It looks like JSONEachRow cannot be used straightforward because the result JSON is not valid.
You can play with grouping data to the array to get valid JSON:
SELECT
groupArray(value) AS values,
groupArray((value, name)) AS objects
FROM
(
SELECT
1 AS value,
'str1' AS name
UNION ALL
SELECT
2 AS value,
'str2' AS name
)
FORMAT JSONEachRow
/* Result:
{"values":[1,2],"objects":[[1,"str1"],[2,"str2"]]}
*/
where you try running your query?
maybe you can try filter this output via pipelines and JQ
clickhouse-client -q "SELECT value FROM test.json_test FORMAT JSON" | jq .data
I have following query which returns the number of request for each status -
r.db.table("request").group("status").count()
result -
[
{
"group": "ACCEPTED",
"reduction": 1
},
{
"group": "DECLINED",
"reduction": 1
},
{
"group": "PENDING",
"reduction": 1
}
]
How can I convert this result to the following using rethinkdb query (javascript)?
{
"ACCEPTED": 1,
"DECLINED": 1,
"PENDING": 1
}
Currently, I am achieving this by iterating the result in api side. But I want this transformation in rethinkdb, if its at all possible?
r.db("test").table("request").group("status").count()
.ungroup()
.map(function(x){ return [x('group'), x('reduction')]; })
.coerceTo("object")
When you want to continue working on your return object you need to
call the ungroup() function first
Then you need to use the map
function to transform your result to:
[ [ "ACCEPTED" , 1 ] , [ "DECLINED" , 1 ] , [ "PENDING" , 1 ] ]
at last you simply transform this to a json-object with coerceTo("object"), which returns you the desired format:
{
"ACCEPTED": 1,
"DECLINED": 1,
"PENDING": 1
}
I have the following data
[{"devcount" : 1 , "dayofweek" :0, "hour" : 1 },
{"devcount" : 2 , "dayofweek" :0, "hour" : 2 },
{"devcount" : 3 , "dayofweek" :1, "hour" : 2 },
{"devcount" : 4 , "dayofweek" :1, "hour" : 3 },
{"devcount" : 6 , "dayofweek" :1, "hour" : 4 },
{"devcount" : 5 , "dayofweek" :1, "hour" : 5 },
{"devcount" : 7 , "dayofweek" :2, "hour" : 5 },
{"devcount" : 8 , "dayofweek" :2, "hour" : 6 },
{"devcount" : 9 , "dayofweek" :2, "hour" : 7 },
{"devcount" : 10 , "dayofweek" :2, "hour" : 9 }]
It is required to compare the devcount with the group average of devcount for each dayofweek.
i.e. for the fist row, devcount=1 is to be compared with the the average device count for the dayofweek-0 (= 1.5) and "yes" to be returned if the devcount is lesser. Else "No" should be returned.
I have coded as below.
smry=d3.nest()
.key( function(d) { return d.dayofweek;})
.rollup(function(d) {return d3.mean(d, function(g) {return g.devcount; })})
.entries(result);
I am not sure how to compare the smry data and the original data.
The original data will be used in selectAll for creating rectangles and the output after comparison needs for determining the colour of the rectangle
You can do it as shown in the snippet below.
test = [{
"devcount": 1,
"dayofweek": 0,
"hour": 1
}, {
"devcount": 2,
"dayofweek": 0,
"hour": 2
},
{
"devcount": 3,
"dayofweek": 1,
"hour": 2
}, {
"devcount": 4,
"dayofweek": 1,
"hour": 3
}, {
"devcount": 6,
"dayofweek": 1,
"hour": 4
}, {
"devcount": 5,
"dayofweek": 1,
"hour": 5
},
{
"devcount": 7,
"dayofweek": 2,
"hour": 5
}, {
"devcount": 8,
"dayofweek": 2,
"hour": 6
}, {
"devcount": 9,
"dayofweek": 2,
"hour": 7
}, {
"devcount": 10,
"dayofweek": 2,
"hour": 9
}
];
//make the summary using nest
smry = d3.nest()
.key(function(d) {
return d.dayofweek;
})
.rollup(function(d) {
return d3.mean(d, function(g) {
return g.devcount;
})
})
.entries(test);
test.forEach(function(t) {
//find the value from summary for dayofweek
var k = smry.find(function(s) {
return (s.key == t.dayofweek)
});
//check the day of week with the mean, set the flag in the data
if(k.values<t.devcount){
t.flag = true;
} else {
t.flag = false;
}
});
console.log(test);//this now has the flag to determine the color
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I have a query that uses group() function:
...group('a','b','c','na').count()
the now the result is returns like in the form of group and reduction like this:
How can I get result without group and reduce in the form of
{
"na": 1285
"c" : 487
"b" : 746
"a" : 32
}
I'm not sure, but I think you're misunderstanding what group does.
The group command takes a property and groups documents by that property. So, for example, if you wanted to group documents by the a property, that would look something like this:
{
a: 1
}, {
a: 1
}, {
a: 1
}, {
a: 2
}
Then you would run the following query:
r.table(...).group('a').count().ungroup()
Which would result in:
[
{
"group": 1 ,
"reduction": 3
},
{
"group": 2 ,
"reduction": 1
}
]
By passing multiple arguments to group you are telling it to make distinct groups for all those properties. So you you have the following documents:
[ {
a: 1, b: 1
}, {
a: 1, b: 1
}, {
a: 1, b: 2
}, {
a: 2, b: 1
}]
And you group them by a and b:
r.table(...).group('a', 'b').count().ungroup()
You will get the following result:
[{
"group": [ 1 , 1 ] ,
"reduction": 2
},
{
"group": [ 1 , 2 ] ,
"reduction": 1
},
{
"group": [ 2 , 1 ] ,
"reduction": 1
}]
Your Answer
So, when you do .group('a','b','c','na').count(), you're grouping them by those 4 properties. If you want the following result:
{
"na": 1285
"c" : 487
"b" : 746
"a" : 32
}
Then your documents should look something like this:
[{
property: 'a'
}, {
property: 'c'
}, {
property: 'na'
},
...
]
And then you would group them in the following way:
r.table(...).group('property').count().ungroup()