I have a issue in Loopback - loopback

I have the following SQL:
SELECT *
FROM table1 INNER JOIN table2 ON table1.id = table2.id_table1
WHERE table2.column_name = 'value';
I have tried
{include:'table2',where:{'table2.column':'value'}}
but can't. What should I do?

this works for me
include: {
relation: 'table2',
scope: {
fields: ['fields', 'you', 'want'],
where: {
column: 'value'
}
}
}
in case it's not working, you need to make sure you have right relations in your table1.json and table2.json file

loopback does not support inner join it only support left join you can use raw query to achieve your requirement try something like this
yourmodalname.customremotemethod= function(ctx,options, cb) {
const ds = yourmodalname.dataSource
var query ="SELECT * FROM table1 INNER JOIN table2 ON table1.id =table2.id_table1 WHERE table2.column_name = 'value'";
ds.connector.query(query, function(err, res){
if(err){
cb(null,err)
}else{
cb(null,res)
}
});
};

Related

Fetching distinct rows from multiple includes with sequelize

I have some nested joins below. I am trying to fetch distinct rows out of it.
Product.findAll({
attributes:[sequelize.fn('DISTINCT', sequelize.col('product.id')), 'product.id']],
include: {
model: Course,
attributes: [],
required: true,
include: {
model: Class,
where: {
classId: args.classId
},
attributes: []
}
}
})
syntax error at or near "DISTINCT"
Query being produced by sequelize,
SELECT "product"."id", DISTINCT("product"."id") AS "product.id" FROM "my_schema"."product_groups" AS "product" INNER JOIN "my_schema"."courses" AS "courses" ON "product"."id" = "courses"."product_group_id" INNER JOIN "my_schema"."classes" AS "courses->classes" ON "courses"."id" = "courses->classes"."course_id" AND "courses->classes"."organization_id" = '68700940-f509-4662-975f-a3ba3382aa9b';;
Working sql query,
SELECT DISTINCT("product"."id") FROM "my_schema"."product_groups" AS "product" INNER JOIN "my_schema"."courses" AS "courses" ON "product"."id" = "courses"."product_group_id" INNER JOIN "my_schema"."classes" AS "courses->classes" ON "courses"."id" = "courses->classes"."course_id" AND "courses->classes"."organization_id" = '68700940-f509-4662-975f-a3ba3382aa9b';
How can I product above query with sequelize to return distinct rows. I also tried distinct: true but it doesn't make any change. With this option query works and returns result but no distinct is there in the query generated.
The DISTINCT syntax in Postgres should look like this.
SELECT DISTINCT column AS alias FROM table;
DISTINCT is a clause and not function so you need to use literal.
Product.findAll({
attributes:[[sequelize.literal('DISTINCT "product"."id"'), 'product.id']],
...
})

Knex, Objection.js, How to sort by number of associations

I have an Express API using Postgres via Knex and Objection.
I want to set up a Model method or scope that returns an array of Parent model instances in order of number of associated Children.
I have looked through the Knex an Objection docs
I have seen the following SQL query that will fit, but trying to figure out how to do this in Knex:
SELECT SUM(O.TotalPrice), C.FirstName, C.LastName
FROM [Order] O JOIN Customer C
ON O.CustomerId = C.Id
GROUP BY C.FirstName, C.LastName
ORDER BY SUM(O.TotalPrice) DESC
This is how it should be done with knex (https://runkit.com/embed/rj4e0eo1d27f):
function sum(colName) {
return knex.raw('SUM(??)', [colName]);
}
knex('Order as O')
.select(sum('O.TotalPrice'), 'C.FirstName', 'C.LastName')
.join('Customer C', 'O.CustomerId', 'C.Id')
.groupBy('C.FirstName', 'C.LastName')
.orderBy(sum('O.TotalPrice'), 'desc')
// Outputs:
// select SUM("O"."TotalPrice"), "C"."FirstName", "C"."LastName"
// from "Order" as "O"
// inner join "Customer C" on "O"."CustomerId" = "C"."Id"
// group by "C"."FirstName", "C"."LastName"
// order by SUM("O"."TotalPrice") desc
But if you are really using objection.js then you should setup models for your Order and Customer tables and do something like this:
await Order.query()
.select(sum('TotalPrice'), 'c.FirstName', 'c.LastName')
.joinRelated('customer as c')
.groupBy('c.FirstName', 'c.LastName')
.orderBy(sum('TotalPrice'), 'desc')
In case anyone is interested, I just included the raw SQL query as follows:
router.get('/leaderboard', async (req, res) => {
let results = await knex.raw('SELECT users_id, username, COUNT(acts.id) FROM acts INNER JOIN users ON acts.users_id = users.id GROUP BY users_id, username ORDER BY COUNT(acts.id) DESC');
console.log(results);
res.json(results.rows);
});

Nested Query Entity Framework

Need help in converting below SQL nested query to a LINQ query?
select P.ProductId, P.Name, C.Name, I.Image
from Product P
join ProductImage I on P.ProductId = I.ProductId
join ProductCategory C on P.Category = C.CategoryId
where P.ProductId in (select distinct ProductId
from ProductVariantMapping M
where M.GUID in (select top 3 V.Guid
from [Order] O
join Inventory V on V.InventoryId = O.InventoryId
group by O.InventoryId, V.Guid
order by Sum(O.Quantity) desc))
Below is my attempt in converting to LINQ query :
var a = (from product in ekartEntities.Products
join productImage in ekartEntities.ProductImages
on product.ProductId equals productImage.ProductId
join category in ekartEntities.ProductCategories
on product.Category equals category.CategoryId
where product.ProductId
select new ProductDTO()
{
ProductId = product.ProductId,
Name = product.Name,
Category = category.Name,
Image = productImage.Image
}).ToList();
what is the equivalent of "IN" when converting to LINQ .
I got the solution for 'IN' clause.
But how do I use sum(Quantity) in order by after grouping?
I am new to Entity Framework. Can anyone help me?
In LINQ, you will need to use the "contains()" method to generate the 'IN' You need to put a list in the Contains method. If sends a query, that query will be repeated for completions and this will lead to performance loss.
Sample:
var sampleList = (from order ekartEntities.Order
join inventory in ekartEntities.Inventory on order.InventoryId equals inventory.InventoryId
select order).toList();
var query = (from product in ekartEntities.Products
join productImage in ekartEntities.ProductImages
on product.ProductId equals productImage.ProductId
join category in ekartEntities.ProductCategories
on product.Category equals category.CategoryId
where sampleList.Contains(product.ProductId)
select new ProductDTO()
{
ProductId = product.ProductId,
Name = product.Name,
Category = category.Name,
Image = productImage.Image
}).ToList();
Do not apply ToList() in the first query
I made some test.
Test 1 (with my own data):
var phIds = new List<string>
{
//List of Ids
};
using (var db = new ApplicationDbContext())
{
var studentsId = db.Relations
.Where(x => phIds.Contains(x.RelationId))
.Select(x => x.Id)
.Distinct(); //IQueryable here
var studentsQuery = from p in db.Students
where studentsId.Contains(p.Id)
select p;
var students= studentsQuery .ToList();
}
The generated query looks like :
SELECT
[Extent1].[Id] AS [Id],
[...]
FROM [dbo].[Students] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM ( SELECT DISTINCT
[Extent2].[StudentId] AS [StudentId]
FROM [dbo].[Relations] AS [Extent2]
WHERE ([Extent2].[RelationId] IN (N'ccd31c3d-dfa3-4b40-...', N'd2cb05a2-ece3-4060-...'))
) AS [Distinct1]
WHERE [Distinct1].[StudentId] = [Extent1].[Id]
)
The query looks exactly like I wanted
However, if you add the ToList() in the first query to get the ids, you no longer have an IQueryable but a list.
Test 2 : wrong (I added ToList):
var phIds = new List<string>
{
//List of Ids
};
using (var db = new ApplicationDbContext())
{
var studentsId = db.Relations
.Where(x => phIds.Contains(x.RelationId))
.Select(x => x.Id)
.Distinct().ToList(); // No longer IQueryable but a list of 3000 int
var studentsQuery = from p in db.Students
where studentsId .Contains(p.Id)
select p;
var students= studentsQuery .ToList();
}
The generated query is ugly:
SELECT
[Extent1].[Id] AS [Id],
[...]
FROM [dbo].[Patients] AS [Extent1]
WHERE [Extent1].[Id] IN (611661, 611662, 611663, 611664,....
//more than 3000 ids here
)

node-postgres LEFT JOIN query

I am attempting to effect a join query in node-postgres (pg) with the following function but am getting a syntax error. The problem is the join query, everything else works fine. What is the correct way to format a join query in pg?
exports.bigBook = function(req, res) {
var bookNumber = req.params.id;
pool.connect(function(err, client, done) {
if (err) { return console.error('error fetching client from pool', err);}
client.query('SELECT * FROM book WHERE id = $1 LEFT JOIN author
ON (book.author = author.auth_id)'), [bookNumber], function (err, results) {
client.release();
res.send(results.rows);
};
})
}
The LEFT JOIN is part of the FROM clause, so you'll have to move the WHERE clause to the end of the query.

How can I execute this Postgres query in Sequelize?

I need to translate this join query into Sequelize. I have associated the three tables involved in the join:
tracks.belongsToMany(tracks_playlists, { foreignKey: 'track_id' });
tracks.belongsToMany(tracks_meta, { foreignKey: 'track_id' });
tracks_meta.belongsToMany(tracks_playlists, { foreignKey: 'track_id'});
Here's the raw query that works:
SELECT tracks_playlists.playlist_id, tracks_playlists.track_id, tracks.track, tracks.track_type, tracks_meta.status, tracks_meta.app_id, tracks_meta.description, tracks_meta.ip
FROM tracks_playlists
INNER JOIN tracks on tracks_playlists.track_id = tracks.track_id
INNER JOIN tracks_meta on tracks.track_id = tracks_meta.track_id
WHERE tracks_playlists.playlist_id = 4;
When I try to run the following code
self.tracks_playlists_table.find({
where: {
playlist_id: 4
},
include: [{
model: self.tracks_table
}]
})
.then(function(resp) {
console.log(resp);
});
it spits out this error:
relation "playlists.trackstracks_playlists" does not exist
This is the query that it generates from my code:
SELECT "TracksPlaylists".*, "Tracks"."track_id" AS "Tracks.track_id",
"Tracks"."track" AS "Tracks.track", "Tracks"."track_type" AS "Tracks.track_type", "Tracks"."created" AS "Tracks.created", "Tracks"."updated" AS "Tracks.updated", "Tracks.trackstracks_playlists"."created" AS "Tracks.trackstracks_playlists.created", "Tracks.trackstracks_playlists"."updated" AS "Tracks.trackstracks_playlists.updated", "Tracks.trackstracks_playlists"."track_id" AS "Tracks.trackstracks_playlists.track_id"
FROM (SELECT "TracksPlaylists"."track_playlist_id", "TracksPlaylists"."track_id", "TracksPlaylists"."playlist_id", "TracksPlaylists"."created", "TracksPlaylists"."updated"
FROM "playlists"."tracks_playlists" AS "TracksPlaylists"
WHERE "TracksPlaylists"."playlist_id" = 4 LIMIT 1) AS "TracksPlaylists"
LEFT OUTER JOIN ("playlists"."trackstracks_playlists" AS "Tracks.trackstracks_playlists"
INNER JOIN "playlists"."tracks" AS "Tracks"
ON "Tracks"."track_id" = "Tracks.trackstracks_playlists"."track_id")
ON "TracksPlaylists"."track_playlist_id" = "Tracks.trackstracks_playlists"."track_id";
Why is it creating the column "trackstracks_playlists"?