I am a beginner in MySQL as well as Typeorm. So my query returns data with the same ID like:
[
{
id: "1",
name: "john",
place: "San Francisco"
},
{
id: "1",
name: "john",
place: "Mumbai"
}
]
Now I want data where there is an entry with a unique id, let's say:
[
{
id: "1",
name: "john",
place: ["San Francisco", "Mumbai"]
}
]
can someone help me, how do I groupBy to achieve this result?
I doubt that you can get an array, but you could use group_concat.
https://mariadb.com/kb/en/group_concat/
The query would be something like
SELECT `id`, group_concat(`name`), group_concat(`place`) FROM <table_name> GROUP BY `id`
if the name doesn't need to be concatenated
SELECT `id`, `name`, group_concat(`place`) FROM <table_name> GROUP BY `id`
And then in your code you can split that string in array. Either use ',' which I think it's the default separator or use a custom one like '!#$!'
With MySQL you can use GROUP_CONCAT:
SELECT
id, name, GROUP_CONCAT(place)
FROM
<table_name>
GROUP BY
id
With TypeScript you can use Array.prototype.reduce():
const data = [{id: "1",name: "john",place: "San Francisco"},{id: "1",name: "john",place: "Mumbai"}]
const dataHash = data.reduce((a, { id, name, place }) => {
a[id] = a[id] || { id, name, place: [] }
a[id].place.push(place)
return a
}, {})
const result = Object.values(dataHash)
console.log(result)
Related
I've got a JSON column containing an array of items:
[
{
"type": "banana"
},
{
"type": "apple"
},
{
"type": "orange"
}
]
I want to select one column with a concatenated type, resulting in 'banana, apple, orange'.
Thanks,
David
You need to parse and aggregate the stored JSON:
SELECT
JsonColumn,
NewColumn = (
SELECT STRING_AGG(JSON_VALUE([value], '$.type'), ',')
WITHIN GROUP (ORDER BY CONVERT(int, [key]))
FROM OPENJSON(t.JsonColumn)
)
FROM (VALUES
('[{"type":"banana"},{"type":"apple"},{"type":"orange"}]')
) t (JsonColumn)
Result:
JsonColumn
NewColumn
[{"type":"banana"},{"type":"apple"},{"type":"orange"}]
banana,apple,orange
I have a mysql Query:-
SELECT #a:=#a+1 serial_number,rule FROM pledges,(SELECT #a:= 0) AS a;
This gives me a serial number along with the rule from the table.
How can I do that in Sequelize?
This is the query I wrote in the model which gives me id and rule:-
Pledge.getPledgeList = function(lang_code='EN') {
return this.findAll({
attributes:['id','rule'],
where: {
status:'a',
deleted_at:null
},
include:[
{ association: 'local', where: {lang_code:lang_code} ,required: false},
]
})
}
I am using below query on my code that is
await to( mymodel.aggregate('cid', 'DISTINCT', {plain: false,where:{created_by:user.id}}));
and query out put on console is
SELECT DISTINCT(`cid`) AS `DISTINCT` FROM `mymodel` AS `mymodel` WHERE `mymodel`.`created_by` = 7;
I got below output that is
ids --------------- [ { DISTINCT: 9 }, { DISTINCT: 10 }, { DISTINCT: 11 } ]
I want to change the alias that is DISTINCT to id. How i do that like below
ids --------------- [ { id: 9 }, { id: 10 }, { id: 11 } ]
I don't think .aggregate() supports aliasing fields however it's simple to turn this into a regular query instead.
await mymodel.findAll({
attributes: [ [ Sequelize.fn('DISTINCT', 'cid'), 'id' ] ],
where: { created_by: user.id }
});
Here we're utilising Sequelize.fn() to create the DISTINCT on cid and using the array attribute notation to alias it to id. More info on this here.
I have rows in my MYSQL and I Need Sequelize.js query.
Every row have col of type JSON what include this for example:
[
{id: 1234, blah: "test"},
{id: 3210, blah: "test"},
{id: 5897, blah: "test"}
]
I have id and I need to select row what include this id in at least one object in array.
Raw mysql query will be like this:
SELECT * FROM `user` WHERE JSON_CONTAINS(`comments`, '{"id": 1234}');
Simple sequelize example:
const { fn, col, cast } = this.sequelize;
const User = this.sequelize.define('user', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
comments: DataTypes.JSON,
defaultValue: [],
})
User.findAll({
where: fn('JSON_CONTAINS', col('comments'), cast('{"id": 1234}', 'CHAR CHARACTER SET utf8')),
})
.then(users => console.log('result', users.map(u => u.get())))
.catch(err => console.log('error', err));
Cast function is used to unescape double quotes around "id" to avoid wrong query string like this:
SELECT * FROM `user` WHERE JSON_CONTAINS(`comments`, '{\"id\": 1234}');
There is one more dirty mysql query example (don't use it):
SELECT * FROM `user` WHERE `comments` LIKE '%"id": 1234%';
I have the following JSON that I'd like to parse inside a postgresql function.
{
"people": [
{
"person_name": "Person#1",
"jobs": [
{
"job_title": "Job#1"
},
{
"job_name": "Job#2"
}
]
}
]
}
I need to know how to pull out the person_name, and then loop thru the jobs and pull out the job_title. This is as far as I've been able to get.
select ('{"people":[{"person_name":"Person#1","jobs":[{"job_title":"Job#1"},
{"job_name":"Job#2"}]}]}')::json -> 'people';
https://www.db-fiddle.com/f/vcgya7WtVdvj8q5ck5TqgX/0
Assuming that job_name in your post should be job_title. I expanded your test data to:
{
"people": [{
"person_name": "Person#1",
"jobs": [{
"job_title": "Job#11"
},
{
"job_title": "Job#12"
}]
},
{
"person_name": "Person#2",
"jobs": [{
"job_title": "Job#21"
},
{
"job_title": "Job#22"
},
{
"job_title": "Job#23"
}]
}]
}
Query:
SELECT
person -> 'person_name' as person_name, -- B
json_array_elements(person -> 'jobs') -> 'job_title' as job_title -- C
FROM (
SELECT
json_array_elements(json_data -> 'people') as person -- A
FROM (
SELECT (
'{"people":[ '
|| '{"person_name":"Person#1","jobs":[{"job_title":"Job#11"}, {"job_title":"Job#12"}]}, '
|| '{"person_name":"Person#2","jobs":[{"job_title":"Job#21"}, {"job_title":"Job#22"}, {"job_title":"Job#23"}]} '
|| ']}'
)::json as json_data
)s
)s
A Getting person array; json_array_elements expands all array elements into one row per element
B Getting person_name from array elements
C Expanding the job array elements into one row per element and getting the job_title
Result:
person_name job_title
----------- ---------
"Person#1" "Job#11"
"Person#1" "Job#12"
"Person#2" "Job#21"
"Person#2" "Job#22"
"Person#2" "Job#23"