-
Notifications
You must be signed in to change notification settings - Fork 27
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
Lines duplicated when ordering on a n-n join table using find() method in the DAO #249
Comments
OverviewThank you for your report ! This problem is kind of tricky as we may not reflect the correct user intent. ReproducibilityI will use the following schema for this comment: Database SetupHere is a MySQL script to set up the issue CREATE TABLE `users` (
`id` INT NOT NULL,
`email` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `roles` (
`id` INT NOT NULL,
`label` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `users_roles` (
`id_user` INT NOT NULL,
`id_role` INT NOT NULL,
PRIMARY KEY (`id_user`, `id_role`),
CONSTRAINT `fk_id_user__users` FOREIGN KEY (`id_user`) REFERENCES `users` (`id`),
CONSTRAINT `fk_id_role__roles` FOREIGN KEY (`id_role`) REFERENCES `roles` (`id`));
INSERT INTO `users` (`id`, `email`) VALUES ('1', 'admin');
INSERT INTO `roles` (`id`, `label`) VALUES ('1', 'a');
INSERT INTO `roles` (`id`, `label`) VALUES ('2', 'b');
INSERT INTO `users_roles` (`id_user`, `id_role`) VALUES ('1', '1');
INSERT INTO `users_roles` (`id_user`, `id_role`) VALUES ('1', '2'); Using the schema and running the generated SQL query leads to the aforementioned issue: SELECT DISTINCT users.*, roles.label
FROM users
JOIN users_roles ON users_roles.id_user = users.id
JOIN roles ON roles.id = users_roles.id_role
ORDER BY roles.label ASC;
A SolutionI guess the best we can try is to use a This would lead to generate something like SELECT users.*, MIN(roles.label) as order_0 -- Here we use `MIN` as the order is `ASC`
FROM users
JOIN users_roles ON users_roles.id_user = users.id
JOIN roles ON roles.id = users_roles.id_role
GROUP BY users.id
ORDER BY order_0 ASC; SELECT users.*, MAX(roles.label) as order_0 -- Here we use `MAX` as the order is `DESC`
FROM users
JOIN users_roles ON users_roles.id_user = users.id
JOIN roles ON roles.id = users_roles.id_role
GROUP BY users.id
ORDER BY order_0 DESC; Notice that we can easily extend this to more order clauses, thus we could have something like: SELECT users.*, MIN(roles.label1) as order_0, MAX(roles.label2) as order_1
FROM users
JOIN users_roles ON users_roles.id_user = users.id
JOIN roles ON roles.id = users_roles.id_role
GROUP BY users.id
ORDER BY order_0 ASC, order_1 DESC; We should care about the Additional notesAlso, PostgreSQL seems to have a
So under the hood it might act the same as the proposed implementation. |
Hey @homersimpsons , hey @ThibBal , Ok, @homersimpsons , your comment is spot on. Wouldn't the right thing to do be to throw an exception instead? |
Data model :
admin_users
table (extendsusers
table)zones
tableadmin_users_zones
table to storeadmin_user_id
,zone_id
Problem encountered: when listing
admin_users
(usingfind()
method inUserDao.php
) with their zones and ordering on them, my lines are duplicated. But the "count" method still returns the correct number.Here is the SQL request generated by TDBM:
Data model creation:
Method called:
->find('', [], 'roles.label ASC')
The text was updated successfully, but these errors were encountered: