Ok. I want these info from each user record.
user.username
user.fullname
report_qty
so the first two fields exist in the user
table. but the last one should be computed from ther tables.
i have a table named reports and there are 3 kind of relation to it
timeline reports (WHERE violated_user_id = someUserId
)
post reports (LEFT JOIN posts ON(posts.id = reports.post_id)
)
image reports (LEFT JOIN images ON(images.id = reports.image_id)
)
so I want something to get these kind of records and fields:
username fullname reports_qty
john_doe john doe 0
jane_doe jane doe 5
the reports_qty
is the sum of timeline/posts/images reports so if jane doe has 2 timeline reports and 2 image reports and 0 post reports that would make a 5 for her reports_qty
field
so far I could make it like this:
SELECT user.username, user.fullname, (
SELECT SUM(cnt) FROM (
SELECT COUNT(report_id) as `cnt` FROM `report` WHERE violated_user_id = $userId
UNION ALL
SELECT COUNT(report_id) as `cnt` FROM report LEFT JOIN blog_post ON (posts.id = report.post_id) WHERE blog_post.user_id = $userId
UNION ALL
SELECT COUNT(report_id) as `cnt` FROM report LEFT JOIN image ON (image.image_id = report.image_id) WHERE image.user_id = $userId
) as `q`
) as `report_qty` FROM user GROUP BY user.id;
as you can see there is this problem that I have to define the $userId
which is wronge. it should take the current record's user.id
and return me the results. how can I do this in mysql? and i am working in codeigniter right know if there is any workaround to this i would appreciate your advices.
EDIT
the table structures and sample data is like this:
I actually removed some unnecessary fields from these fields but this should do.
REPORT TABLE:
CREATE TABLE `report` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`image_id` INT(11) NULL DEFAULT NULL,
`post_id` INT(11) NULL DEFAULT NULL,
`violated_user_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `violated_user_id` (`violated_user_id`),
INDEX `image_id` (`image_id`),
INDEX `post_id` (`post_id`),
CONSTRAINT `FK__user` FOREIGN KEY (`violated_user_id`) REFERENCES `user` (`user_id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_report_posts` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_report_images` FOREIGN KEY (`image_id`) REFERENCES `images` (`image_id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=91
;
SAMPLE DATA RECORDS FOR REPORT:
TIMELINE REPORT
INSERT INTO `report` (`id`, `image_id`, `post_id`, `violated_user_id`) VALUES (1, NULL, NULL, 1);
POST REPORT
INSERT INTO `report` (`id`, `image_id`, `post_id`, `violated_user_id`) VALUES (2, NULL, 1, NULL);
IMAGE REPORT
INSERT INTO `report` (`id`, `image_id`, `post_id`, `violated_user_id`) VALUES (3, 1, NULL, 2);
IMAGES TABLE:
CREATE TABLE `images` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL,
`image` VARCHAR(64) NOT NULL,
PRIMARY KEY (`id`),
INDEX `user_id` (`user_id`),
CONSTRAINT `FK_image_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=5
;
IMAGES SAMPLE DATA RECORDS:
FIRST USER'S POST
INSERT INTO `images` (`id`, `user_id`, `image`) VALUES (1, 1, '8899c3fecc6afd8cd54a806fc8402bde.jpg');
POSTS TABLE:
CREATE TABLE `posts` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NULL DEFAULT NULL,
`text` TEXT NOT NULL,
PRIMARY KEY (`id`),
INDEX `user_id` (`user_id`),
FULLTEXT INDEX `text` (`text`),
CONSTRAINT `FK_post_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=61
;
USER'S POSTS SAMPLE DATA:
FIRST USER
INSERT INTO `posts` (`id`, `user_id`, `text`) VALUES (1, 1, 'aaaaaaaaaaaa');
**USERS TABLE:**
CREATE TABLE `user` (
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(32) NOT NULL COLLATE 'utf8mb4_bin',
`fullname` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_bin',
`email` VARCHAR(128) NOT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`user_id`),
UNIQUE INDEX `user_name` (`username`),
UNIQUE INDEX `email` (`email`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=8
;
USERS SAMPLE DATA:
FIRST USER'S RECORD
INSERT INTO `user` (`id`, `username`, `email`) VALUES (1, 'm-f-r', 'eagle.seeing@yahoo.com');
Best Answer
There are several inconsistencies in your code, for example:
and
I changed the id field of
user
table to beid
in theuser
table and all the foreign key references.Then you mention table
blog_post
in your attempt, which doesn't appear in your sample data. I'm assumingblog_post
is the same asposts
.Once you fix all that, your query changes into:
... which doesn't work, because the inner-most query can't see the table
user
from the outer-most query.Instead of doing so much nesting, you can get rid of the middle
SELECT
and add the three counts, making the query work:But then you can notice that all the tables refer to
user.id
, so you can get rid of the joins in the subqueries:Finally, you can rewrite this query using joins instead of subqueries:
This fixes the problem of your query.
There is now a problem with your database design which has many flaws:
Is the
user_id
field necessary inimages
andposts
?What is the relationship between
images
records andreport
record?etc...