SELECT "count"(DISTINCT("displayedCandidates"))
from
(SELECT unnest("displayedCandidates") "displayedCandidates" FROM roles)
"displayedCandidates"
here the "displayedCandidates" column is of the type of string array which contains relevant candidateIds.What I want to query is the distinct count of displayed candidates.And this sql query is properly working.
Try this:
return model.findAll({
attributes: ['candidateId', 'displayedCandidates'],
where: {
candidateId: {
[Op.in]: sequelize.literal('(SELECT unnest("displayedCandidates") as
"displayedCandidates" FROM "Roles" WHERE "candidateId" ='+ '\'' + candidateId + '\')'
)
}
}
})
.then((model) => {
console.log(model);
})
.catch((err) => {
console.log(err);
});
Read the documentation, this might help you.
Sequelize Querying
Related
How can we get the list of all blogs group by tags from the userblogs table
sql query below:
select max(id) as id, max(blogdetails) as blog, tags, count (tags) as tagcount from userblogs group by tags;
I have tried so far;
app.get('/service/listofblogs', async (req, res) => {
try {
const blogData = await BlogModel.findAll(
{attributes: ['blogdetails', 'tags']},
{ group: ['tags'] }
);
res.status(200).json({ blogData });
} catch (e) {
res.status(500).json({ message: e.message });
}
});
Can you try with single value instead of array?
const blogData = await BlogModel.findAll(
{attributes: ['blogdetails', 'tags']},
{ group: 'tags' }
);
Is there any way in strapi to group by entries with the same fields and count its total?
Trying to create a Poll App which has "Response" Collection containing an "Answer" Field (enum: a, b, c, d). Would like to group responses with the same answers. Something like this:
{
"answer": "a",
"total": 3
}, {
"answer": "b",
"total": 1
}
Is it possible out of the box?
To give more context, here's its sql counterpart:
select *, count(answers) from responses group by answers
there is no known default way for groupby with entity service, however there is count query:
/src/answer/controllers/answer.js
const { createCoreController } = require("#strapi/strapi").factories;
module.exports = createCoreController("api::answer.answer", ({ strapi }) => ({
async find(ctx) {
let { query } = ctx;
let answers = await strapi.db.query("api::answer.answer").findMany({
...query,
});
answers = await Promise.all(answers.map(async (answer) => ({
...answer,
total: await strapi.db.query("api::answer.answer").count({where: '...'})
})))
return answers
},
}));
or you can use raw query like this:
let { rows } = await strapi.db.connection.raw(
`select id from posts where published_at IS NOT null order by random() limit ${count};
`);
or
let { rows } = await strapi.db.connection.raw(
`select *, count(answers) from responses group by answers;`);
I want to find the highest value in a specific column of a specific table. It should be very simple.
this is the documentation of LB4 https://loopback.io/doc/en/lb2/Where-filter But I didn't find it there.
We did this through a custom repository method where we execute a select max() query and have a custom controller method (i.e. /next-id) that calls it.
Repository method:
async nextId(): Promise<any> {
return this.dataSource
.execute('select MAX(id)+5 as nextId from route_lookup')
.then(data => {
if (data[0].NEXTID === null) {
data[0].NEXTID = 1005;
}
return data[0].NEXTID;
});
}
Controller method:
#get('/route-lookups/next-id')
#response(200, {
description: 'Next avaialble id for route lookup',
content: {
'application/json': {
schema: {
type: 'number',
},
},
},
})
async nextId(): Promise<number> {
return await this.routeLookupRepository.nextId();
}
Within the Loopback Filter Documentation they do mention a way to achieve this, even though it's not as obvious.
/weapons?filter[where][effectiveRange][gt]=900&filter[limit]=3
Essentially you can do the following:
Identify the column of interest.
Use the gt operator to set a min number
Add order if you wanted to ensure the sorting order is as expected.
Limit the results to 1.
Here is a code example:
Employees.find({
where: {
age: {
gt: 1
}
},
order: 'age ASC',
limit: 1
})
Please let me know if this is what you were going for or if you need some more support.
I developed typeorm querybuilder. For the purpose of debugging, I'd like to show the generated SQL query.
I tested printSql() method, but it didn't show any SQL query.
const Result = await this.attendanceRepository
.createQueryBuilder("attendance")
.innerJoin("attendance.child", "child")
.select(["attendance.childId","child.class","CONCAT(child.firstName, child.lastName)"])
.where("attendance.id= :id", { id: id })
.printSql()
.getOne()
console.log(Result);
It returned the following:
Attendance { childId: 4, child: Child { class: 'S' } }
My desired result is to get the generated SQL query.
Is there any wrong point? Is there any good way to get the SQL query?
.getQuery() or .getSql()
const sql1 = await this.attendanceRepository
.createQueryBuilder("attendance")
.innerJoin("attendance.child", "child")
.select(["attendance.childId","child.class","CONCAT(child.firstName, child.lastName)"])
.where("attendance.id= :id", { id: id })
.getQuery();
console.log(sql1);
const sql2 = await this.attendanceRepository
.createQueryBuilder("attendance")
.innerJoin("attendance.child", "child")
.select(["attendance.childId","child.class","CONCAT(child.firstName, child.lastName)"])
.where("attendance.id= :id", { id: id })
.getSql();
console.log(sql2);
printSql can also be used, but it will only print when logging is enabled.
#Module({
imports: [
TypeOrmModule.forRoot({
...options
logging: true
}),
],
})
await this.attendanceRepository
.createQueryBuilder("attendance")
.innerJoin("attendance.child", "child")
.select(["attendance.childId","child.class","CONCAT(child.firstName, child.lastName)"])
.where("attendance.id= :id", { id: id })
.printSql();
Still a little new to Node but this is driving me nuts. I have looked around but cannot find an existing answer that has helped me yet. I know I'm missing something stupid I'm sure. My elements appear to be mapping correctly. I have triple checked my columns and my values. I've even taken the SQL query from my debug session in Visual Studio code and run it directly in DBVis, no issues. But for some reason when I run this in Node I always get "Error: SQLITE_RANGE: bind or column index out of range". Are there any known issues with mapping elements in node and SQLite Im unfamiliar with?? Im using the map function and sql function in other places and it seems to be working fine. Just not here.
Here is the relevant code.
exports.createUserGoogle = createUserGoogle;
function createUserGoogle(jsonObj, cb) {
var sql = "Begin;"
+"Insert into userGoogle (googleId,token,name,email,photoid) values ($googleid,$googleToken,$name,$email,$photoid);"
+"Commit;";
doSQL(sql, mapDataElements(jsonObj), cb);
}
My mapping function
function mapDataElements(jsonObj) {
dataObj = {};
for (key in jsonObj) {
dataObj['$' + key] = jsonObj[key];
}
console.log('mapDataElements: Mapped as: ' + JSON.stringify(dataObj));
return dataObj;
}
My Standard SQL Promise function
function doSQL(sqlStr, bindings, cb) {
var p = new Promise((resolve, reject) => {
db.serialize(() => {
db.run(sqlStr, bindings, (err) => {
if (err) {
console.log('SQL failed: ' + JSON.stringify(bindings));
reject(err);
}
else {
console.log('SQL succeeded: ' + sqlStr);
resolve();
}
});
});
});
p.then(
(data) => {
console.log('Doing callback');
cb('success');
},
(err) => {
cb(null, err);
}
);
}
Also here are what my mapped elements look like (slightly edited for security):
mapDataElements: Mapped as: {"$googleid":"mylongnumber","$googleToken":"myreallylongtokenvalue","$name":"My name","$email":"my.email#gmail.com","$photoid":1}
Any my table if it helps
CREATE TABLE userGoogle(
pk_google INTEGER NOT NULL PRIMARY KEY,
googleId TEXT,
token TEXT,
name TEXT,
email TEXT,
photoid int,
FOREIGN Key(photoid) References photo(pk_photo)
);
I solved similar problem by using db.exec() instead of db.run(). As db.exec() doesn't accept parameters I had to make correct sql query string myself.