How to add AND condition when use inner join on Sequelize - node.js

I have some sql code like this
select *
from people_work_attendances pwa
inner join people_work_placements pwp on pwa.user_work_id = pwp.id
inner join company_job_profile_r_attendance cjpa on pwp.job_profile = cjpa.profile and pwa.policy_id=cjpa.policy
WHERE
pwa.user_work_id = 71072
and cjpa.profile IS NOT NULL
i want to implement this section to Sequelize
inner join company_job_profile_r_attendance cjpa on pwp.job_profile = cjpa.profile and pwa.policy_id=cjpa.policy
current situation is i can make it like this
if(!module.exports.Placement.associations.JobProfileAttendance){
module.exports.Placement.hasOne(module.exports.JobProfileAttendance, {
as:'JobProfileAttendance',
sourceKey:'jobProfile',
foreignKey:'profile'
})
}
but the result of this part is like this
INNER JOIN "public"."company_job_profile_r_attendance" AS "Placement->JobProfileAttendance" ON "Placement"."job_profile" = "Placement->JobProfileAttendance"."profile"
i want to make like this
INNER JOIN "public"."company_job_profile_r_attendance" AS "Placement->JobProfileAttendance"
ON "Placement"."job_profile" = "Placement->JobProfileAttendance"."profile"
AND "PeopleWorkAttendance"."policy_id" = "Placement->JobProfileAttendance"."policy"
want to add some AND conditions but in Sequelize
AND "PeopleWorkAttendance"."policy_id" = "Placement->JobProfileAttendance"."policy"

You can use on option in include, just keep in mind that you always should do it manually because Sequelize doesn't support composite primary and foreign keys.
See options.include[].on in findAll options

Related

How to pass WHERE clause to Sequelize generated subqueries?

I have a Sequelize view that uses joins like this:
select * from tableA left join (select * from tableB where someKey={some input}) newTableB on tableA.someId = newTableB.someId
Now, when I create a view from this query, I can create a sequelize model for it. But, I want to execute the query in sequelize... like -
models.tableView.findAll({ some clause })
In the above where clause, I want to pass the value of someKey (referring to someKey={some input} in the sample view). How do I do that?
I don't want to fetch all data and then apply the tableB.someKey=something (as that will take far more time)

Is it possible to chain subsequent queries's where clauses in Dapper based on the results of a previous query in the same connection?

Is it possible to use .QueryMultiple (or some other method) in Dapper, and use the results of each former query to be used in the where clause of the next query, without having to do each query individually, get the id, and then .Query again, get the id and so on.
For example,
string sqlString = #"select tableA_id from tableA where tableA_lastname = #lastname;
select tableB_id from tableB WHERE tableB_id = tableA_id";
db.QueryMultiple.(sqlString, new {lastname = "smith"});
Is something like this possible with Dapper or do I need a view or stored procedure to accomplish this? I can use multiple joins for one SQL statement, but in my real query there are 7 joins, and I didn't think I should return 7 objects.
Right now I'm just using object.
You can store every previous query in table parameter and then first perform select from the parameter and query for next, for example:
DECLARE #TableA AS Table(
tableA_id INT
-- ... all other columns you need..
)
INSERT #TableA
SELECT tableA_id
FROM tableA
WHERE tableA_lastname = #lastname
SELECT *
FROM #TableA
SELECT tableB_id
FROM tableB
JOIN tableA ON tableB_id = tableA_id

NodeJS Sequelize and FindAll with Include and constraints

I am trying to use the Include capabilities in the Find all to Eager load the data i need in a single query. My issue is that all the includes are LEFT OUTER JOIN ... which is good but i am not seeing a way to add additional constraints to that LEFT OUTER JOIN.
My query would look something like:
Matches.findAll(
{where: ["match.isPublished = ?", true],
include: [RoundMaps,
Locations,
{model: MemberMaps, as: "MemberMaps", where: ["memberMaps.memberUUID = ?", authenticatedUser.uuid]}]})
But this does not seem to be supported ... at least the way i have the syntax written. I cannot add that constraint to the constraints on the LEFT OUTER JOIN ... adding the same constraint to the WHERE clause does not work ... as that gives me only the Matches that the Member is associated with. I want the list of all public Matches and to know which of those that the member has already established an association.
Can it be done?
Sequelize seems to be getting most things done! But still struggling with some things.
Insights welcome!
Cheers
According to your question this is not possible using where clause with LEFT OUTER JOIN.
For this you have to write SQL queries to list of all public Matches and to know which of those that the member has already established an association.
sequelize.query('SELECT * FROM "Matches" LEFT OUTER JOIN "RoundMaps" ON "Matches".id = "RoundMaps".match_id LEFT OUTER JOIN "Locations" ON "Matches".id = "Locations".match_id LEFT OUTER JOIN (SELECT * FROM "MemberMaps" WHERE "MemberMaps".memberUUID = ?) AS "MemberMaps" ON "Matches".id = "MemberMaps".match_id WHERE "Matches".isPublished = ?', null, { raw: true }, [memberUUID,true ]).success(function(myTableRows) {
console.log(myTableRows);
res.send(myTableRows);
});
Executing raw SQL queries in Sequelize
There is an option on INCLUDE that specifies whether the join will be inner or outer: include.require = boolean
When there isn't a where: clause specified, then it defaults to false. But, it gets set to true when a where: is set.
You can explicitly turn that off to fetch all of the results of the findAll().
Unfortunately, the only examples I've seen of this are in the codebase itself, but here it is:
sequelize/test/integration/associations/belongs-to-many.test.js#L167

Subsonic 3 Simple Query inner join sql syntax

I want to perform a simple join on two tables (BusinessUnit and UserBusinessUnit), so I can get a list of all BusinessUnits allocated to a given user.
The first attempt works, but there's no override of Select which allows me to restrict the columns returned (I get all columns from both tables):
var db = new KensDB();
SqlQuery query = db.Select
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
The second attept allows the column name restriction, but the generated sql contains pluralised table names (?)
SqlQuery query = new Select( new string[] { BusinessUnitTable.IdColumn, BusinessUnitTable.NameColumn } )
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
Produces...
SELECT [BusinessUnits].[Id], [BusinessUnits].[Name]
FROM [BusinessUnits]
INNER JOIN [UserBusinessUnits]
ON [BusinessUnits].[Id] = [UserBusinessUnits].[BusinessUnitId]
WHERE [BusinessUnits].[RecordStatus] = #0
AND [UserBusinessUnits].[UserId] = #1
So, two questions:
- How do I restrict the columns returned in method 1?
- Why does method 2 pluralise the column names in the generated SQL (and can I get round this?)
I'm using 3.0.0.3...
So far my experience with 3.0.0.3 suggests that this is not possible yet with the query tool, although it is with version 2.
I think the preferred method (so far) with version 3 is to use a linq query with something like:
var busUnits = from b in BusinessUnit.All()
join u in UserBusinessUnit.All() on b.Id equals u.BusinessUnitId
select b;
I ran into the pluralized table names myself, but it was because I'd only re-run one template after making schema changes.
Once I re-ran all the templates, the plural table names went away.
Try re-running all 4 templates and see if that solves it for you.

SubSonic.SqlQuery incorrectly generated when using Where()

I am using version 2.1 of SubSonic. I am trying to build to build a relatively simple query where I get a list of Roles for a User using UserId as a parameter. (UserId is a string...)
SubSonic.SqlQuery sel = new SubSonic.Select().From(Data.Tables.Role).InnerJoin(Data.Tables.UserRole, Data.UserRole.Columns.RoleId, Data.Tables.Role, Data.Role.Columns.Id).InnerJoin(Data.Tables.User, Data.User.Columns.Id, Data.Tables.UserRole, Data.UserRole.Columns.UserId).Where("[dbo].[User].[Id]").IsEqualTo(userId);
this generates the query
SELECT [dbo].[Role].[Id], [dbo].[Role].[PID], [dbo].[Role].[Name]
FROM [dbo].[Role]
INNER JOIN [dbo].[UserRole] ON [dbo].[Role].[Id] = [dbo].[UserRole].[RoleId]
INNER JOIN [dbo].[User] ON [dbo].[UserRole].[UserId] = [dbo].[User].[Id]
WHERE [dbo].[User].[Id] = #[dbo].[User].[Id]0
which fails. If I replace the Where with .Where(Data.User.Columns.Id) this generates the query
SELECT [dbo].[Role].[Id], [dbo].[Role].[PID], [dbo].[Role].[Name]
FROM [dbo].[Role]
INNER JOIN [dbo].[UserRole] ON [dbo].[Role].[Id] = [dbo].[UserRole].[RoleId]
INNER JOIN [dbo].[User] ON [dbo].[UserRole].[UserId] = [dbo].[User].[Id]
WHERE [dbo].[Role].[Id] = #Id0
which uses the Role table in the Where clause instead of the User table.
Is this a bug, or am I doing something incorrectly? What would be the correct way to do this? Thanks.
This is fixed in version 2.2 - I would suggest upgrading.

Resources