-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to find a records with two or more relationships? #1585
Comments
Other columns? Well yes obviously, you're including a relation :) You can use You might want to try: having: ['COUNT(?) >= ?', '`photo_tag_relation`.`photo_id`', 2] |
I did it with two queries: db.models.PhotoTagRelation
.findAll({
include: [
{model: db.models.Tag, where: {name: ['tefal', 'iron']}}
],
group: ['photo_id'],
having: ['COUNT(?) >= ?', '`photo_id`', 2]
})
.success(function(result){
db.models.Photo
.findAndCountAll({
where: {id: result.map( function(item){ return item.photo_id } )}
})
.success(function( result ){
})
}) But i want to do it in one query, can i get assemble query?
or put subquery to where option like this:
|
No it's not possible to combine find calls like that. Did you try what i suggested? |
No, i didn't. I do not understand what you mean, because your code is similar to mine. Can write a complete example, please? |
Similar but different, i targeted a more specific field. Well try out my change first and show me how the SQL looks like and what error it logs, i don't have any experience with HAVING so i can't write up a full example. |
Query is valid ( my query also ) SELECT `photo_tag_relations`.`photo_id`,
`photo_tag_relations`.`tag_id` AS
`photo_tag_relations.tag_id`,
`photo_tag_relations`.`photo_id` AS
`photo_tag_relations.vobject_uuid`
FROM `tag`
LEFT OUTER JOIN `photo_tag_relation` AS `photo_tag_relations`
ON `tag`.`id` = `photo_tag_relations`.`tag_id`
WHERE `tag`.`name` IN ( 'tefal', 'iron' )
GROUP BY `photo_tag_relations`.`photo_id`
HAVING Count('`photo_tag_relation`.`photo_id`') >= 2; I find solution... |
Great, it works? :) |
I find solution how do it in one query. I have the following JS code: db.models
.Vobject
.findAndCountAll({
where: [{type: 1 }],
include: [{model: db.models.Tag, where: {name: ['iron', 'tefal']}}],
limit: 10
}) The problem is that sequelize generates the following query:
For example: SELECT attributes
FROM (SELECT `vobject`.*
FROM `vobject`
WHERE ( `vobject`.`type` = 1 )
LIMIT 10) AS `vobject`
INNER JOIN `vobject_tag_to_vobject` AS
`vobject_tags.vobject_tag_to_vobject`
ON `vobject`.`uuid` =
`vobject_tags.vobject_tag_to_vobject`.`vobject_uuid`
INNER JOIN `vobject_tag` AS `vobject_tags`
ON `vobject_tags`.`id` =
`vobject_tags.vobject_tag_to_vobject`.`tag_id`
AND `vobject_tags`.`name` IN ( 'iron', 'tefal' ); But I need the generated SQL query to look like this:
For example: SELECT attributes
FROM `vobject`
INNER JOIN `vobject_tag_to_vobject` AS
`vobject_tags.vobject_tag_to_vobject`
ON `vobject`.`uuid` =
`vobject_tags.vobject_tag_to_vobject`.`vobject_uuid`
INNER JOIN `vobject_tag` AS `vobject_tags`
ON `vobject_tags`.`id` =
`vobject_tags.vobject_tag_to_vobject`.`tag_id`
AND `vobject_tags`.`name` IN ( 'iron', 'tefal' )
WHERE ( `vobject`.`type` = 1 )
LIMIT 10; This happens because of the subquery requirement check in QueryGenerator.selectQuery , subQuery = limit && (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation ) After, I created the option.filterByInclude and added it to the condition, everything started to work fine :) , subQuery = limit && !option.filterByInclude (options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation ) Now it returns objects with either 'iron' or 'tefal' tag. The next step is to find object with both 'iron' and 'tefal' tags. I modified my query as follows:
db.models
.Vobject
.findAndCountAll({
where: [{type: 1 }],
include: [{model: db.models.Tag, where: {name: ['iron', 'tefal']}}],
limit: 10,
filterByInclude: true,
group: ['`vobject`.`uuid`'],
having: ['COUNT(?) >= ?', '`vobject`.`uuid`', 2]
}) SELECT attributes...
FROM `vobject`
INNER JOIN `vobject_tag_to_vobject` AS
`vobject_tags.vobject_tag_to_vobject`
ON `vobject`.`uuid` =
`vobject_tags.vobject_tag_to_vobject`.`vobject_uuid`
INNER JOIN `vobject_tag` AS `vobject_tags`
ON `vobject_tags`.`id` =
`vobject_tags.vobject_tag_to_vobject`.`tag_id`
AND `vobject_tags`.`name` IN ( 'iron', 'tefal' )
WHERE ( `vobject`.`type` = 1 )
GROUP BY `vobject`.`uuid`
HAVING Count('`vobject`.`uuid`') >= 2
LIMIT 10; Hurray, it works! But the count is broken now, it has a value of '2'. This query returns 35 rows (the previous query returns the same number of rows) and each row has count equal to '2'. This happens because of the GROUP BY clause: SELECT Count(`vobject`.`uuid`) AS `count`
FROM `vobject`
INNER JOIN `vobject_tag_to_vobject` AS
`vobject_tags.vobject_tag_to_vobject`
ON `vobject`.`uuid` =
`vobject_tags.vobject_tag_to_vobject`.`vobject_uuid`
INNER JOIN `vobject_tag` AS `vobject_tags`
ON `vobject_tags`.`id` =
`vobject_tags.vobject_tag_to_vobject`.`tag_id`
AND `vobject_tags`.`name` IN ( 'iron', 'tefal' )
WHERE ( `vobject`.`type` = 1 )
GROUP BY `vobject`.`uuid`
HAVING Count('`vobject`.`uuid`') >= 2; To make this work we need to move the main query into subquery: SELECT COUNT(*) as count FROM (
SELECT `vobject`.`uuid` AS `count`
FROM `vobject`
INNER JOIN `vobject_tag_to_vobject` AS
`vobject_tags.vobject_tag_to_vobject`
ON `vobject`.`uuid` =
`vobject_tags.vobject_tag_to_vobject`.`vobject_uuid`
INNER JOIN `vobject_tag` AS `vobject_tags`
ON `vobject_tags`.`id` =
`vobject_tags.vobject_tag_to_vobject`.`tag_id`
AND `vobject_tags`.`name` IN ( 'iron', 'tefal' )
WHERE ( `vobject`.`type` = 1 )
GROUP BY `vobject`.`uuid`
HAVING Count('`vobject`.`uuid`') >= 2
) as tmp; Modify DAOFactory.prototype.count options.attributes = [
[this.sequelize.fn('COUNT', col), 'count']
]
// change to
options.count = true;
options.attributes = [col] Modify QueryGenerator.selectQuery // add before the end of query
if(options.count) {
query = 'SELECT COUNT(*) as count FROM (' + query + ') as tmp';
}
query += ";"; Now everything works as it should :) |
Very specific solution, but glad you worked it out for your problem :) |
啊呀...... |
How to find a records with two or more relationships using SequelizeJS?
For example:
Find photos with exactly two tags:
I tried to create a subquery:
However the resulting query contains other columns besides 'photo_id':
The text was updated successfully, but these errors were encountered: