Generate Prefix Number ID with Condition By Group ID - mysql

First this is my table
CREATE TABLE IF NOT EXISTS `group` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `member` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`group_id` int(11) unsigned NOT NULL,
`code` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `group_id` (`group_id`),
FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I need member.id look like 001, 002, 003. . i following lpad(id, 3, 0) and case close
But how to reset 001, 002, 003 back to 001 again where have different group_id
This query have result 01-001, 01-002, 02-003, 03-004 (group.id - member.id)
SELECT CONCAT(lpad(g.id, 2, 0),'-',lpad(m.id, 3, 0)) AS id, m.name
FROM member m
LEFT JOIN group g ON g.id = m.group_id
ORDER BY m.id ASC
Please help, i need 01-001, 01-002, 02-001, 03-001 (group.id - member.id)
Or can i use trigger to make my member.code auto generate when insert to 01-001, 01-002, 02-003, 03-004 base on group.id - member.id

Related

need help in writing complex sql query with join and with case

Here is SQL Fiddle
Expected output is below:
id | firstname. | lastname. | country.| followerscount.| followingcount.| BottonText
------------------------------------------------------------------------------------
54 prince lal nepal 1 1 Unfollow
56. Rekha. Gupta United States 1 0 Unfollow
57. Nirmal null null 0 1 Follow Back
I tried below query assuming current logged in UserId= 55 & compare with other users. Can you write the correct query, it can be with join, i just need the output,query can be anything
TRY1
SELECT
u.user_id AS id, u.first_name AS firstname,u.last_name AS lastname,u.country as country,
(select count(uf.following_user_id) from user_follow uf where uf.followed_user_id=u.user_id)as followerscount,
(select count(uf.followed_user_id) from user_follow uf where uf.following_user_id=u.user_id)as followingcount,
CASE
WHEN uuf.following_user_id=55 AND uuf.followed_user_id=u.user_id THEN "Unfollow" # A is following B == unfollow
WHEN uuf.following_user_id=u.user_id AND uuf.followed_user_id NOT IN(55) THEN "Follow Back" #B is following A but A is not following B = followBack
ELSE "Follow"
END AS BottonText
FROM userdetails u,user_follow uuf
WHERE u.user_id NOT IN(55) AND u.record_status=1
TRY2
SELECT
u.user_id,
(count(uf.following_user_id)) as followers,
CASE
WHEN uf.following_user_id=55 AND uf.followed_user_id=u.user_id THEN "Unfollow" # A is following B == unfollow
WHEN uf.following_user_id=u.user_id AND uf.followed_user_id=55 AND uf.following_user_id !=55 AND uf.followed_user_id !=u.user_id
THEN "Follow Back" #B is following A but A is not following B = followBack
ELSE "Follow"
END AS BottonText,
(select count(uf.followed_user_id)
from user_follow uf
where uf.following_user_id = u.user_id) as following
from
(userdetails u left outer join user_follow uf on uf.followed_user_id=u.user_id)
where u.record_status=1 and u.user_id NOT IN(55)
group by u.user_id
Table defination
CREATE TABLE `userdetails` (
`user_id` int(11) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) DEFAULT NULL,
`country` varchar(30) DEFAULT NULL,
`avatar_img_name` varchar(30) DEFAULT NULL,
`record_status` int(1) NOT NULL COMMENT '1- active'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `userdetails`
ADD PRIMARY KEY (`user_id`);
CREATE TABLE `user_follow` (
`id` int(11) NOT NULL,
`following_user_id` int(11) NOT NULL,
`followed_user_id` int(11) NOT NULL,
`created_date` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
#following_user_id and followed_user_id are foriegn key associated userdetails user_id
http://sqlfiddle.com/#!9/90d4ac/18
schema:
CREATE TABLE `userdetails` (
`user_id` int(11) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) DEFAULT NULL,
`country` varchar(30) DEFAULT NULL,
`avatar_img_name` varchar(30) DEFAULT NULL,
`record_status` int(1) NOT NULL COMMENT '1- active'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `userdetails`
ADD PRIMARY KEY (`user_id`);
INSERT INTO `userdetails` (`user_id`, `first_name`, `last_name`, `country`, `avatar_img_name`, `record_status`) VALUES
(1, 'Admin', 'Admin', 'India', NULL, 0),
(54, 'Prince', 'Lal', 'Nepal', 'p.jpg', 1),
(55, 'ashutosh', 'Singh', 'Afganistan', 'a.jpg', 1),
(56, 'Rekha', 'Gupta', 'United States', 'r.jpg', 1),
(57, 'Nirmal', NULL, NULL, NULL, 1);
CREATE TABLE `user_follow` (
`id` int(11) NOT NULL,
`following_user_id` int(11) NOT NULL,
`followed_user_id` int(11) NOT NULL,
`created_date` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `user_follow` (`id`, `following_user_id`, `followed_user_id`, `created_date`) VALUES
(1, 55, 56, '2021-02-07 02:14:26'),
(2, 55, 54, '2021-02-06 01:14:26'),
(3, 54, 55, '2021-02-07 10:33:45'),
(4, 57, 55, '2021-02-07 00:00:00');
ALTER TABLE `user_follow`
ADD PRIMARY KEY (`id`),
ADD KEY `following_user_id` (`following_user_id`),
ADD KEY `followed_user_id` (`followed_user_id`);
ALTER TABLE `user_follow`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
ALTER TABLE `user_follow`
ADD CONSTRAINT `user_follow_ibfk_1` FOREIGN KEY (`followed_user_id`) REFERENCES `userdetails` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `user_follow_ibfk_2` FOREIGN KEY (`following_user_id`) REFERENCES `userdetails` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
query:
SELECT
u.user_id, u.first_name, u.last_name, u.country,
(SELECT COUNT(*) FROM user_follow uf1 WHERE uf1.followed_user_id=u.user_id) AS followerscount,
(SELECT COUNT(*) FROM user_follow uf2 WHERE uf2.following_user_id=u.user_id) AS followingcount,
IF(
EXISTS(SELECT * FROM user_follow uf3 -- if I'm following the specified user
WHERE uf3.following_user_id=55 AND uf3.followed_user_id=u.user_id),
'Unfollow', -- then show 'unfollow button'
IF(
EXISTS(SELECT * FROM user_follow uf4 -- if the specified user is following me
WHERE uf4.followed_user_id=55 AND uf4.following_user_id=u.user_id),
'Follow Back', -- then show 'follow back button'
'Follow') -- then show 'follow button'
) AS ButtonText
FROM
userdetails u
WHERE
u.user_id<>55
AND u.user_id<>1 -- should not select the admin user
explanation: it seems that the expected table is based on "userdetails" table, so you should only select "userdetails" in FROM clause, and add other column with subquery in SELECT clause

how to count same rating from field in sql

I have a problem counting ratings in SQL. This is what my data looks like:
data
CREATE TABLE `restaurant` (
`id_restaurant` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id_restaurant`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
insert into `restaurant`(`id_restaurant`,`name`) values (1,'Mc Donald');
insert into `restaurant`(`id_restaurant`,`name`) values (2,'KFC');
CREATE TABLE `user` (
`id_user` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id_user`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
insert into `user`(`id_user`,`userName`) values (1,'Audey');
CREATE TABLE `factors` (
`factor_id` int(11) NOT NULL AUTO_INCREMENT,
`factor_clean` int(11) NOT NULL DEFAULT '0',
`factor_delicious` int(11) NOT NULL DEFAULT '0',
`id_restaurant` int(11) DEFAULT NULL,
`id_user` int(11) DEFAULT NULL,
PRIMARY KEY (`factor_id`),
KEY `id_restaurant` (`id_restaurant`),
KEY `id_user` (`id_user`),
CONSTRAINT `factors_ibfk_1` FOREIGN KEY (`id_restaurant`) REFERENCES `restaurant` (`id_restaurant`),
CONSTRAINT `factors_ibfk_2` FOREIGN KEY (`id_user`) REFERENCES `user` (`id_user`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
insert into `factors`(`factor_id`,`factor_clean`,`factor_delicious`,`id_restaurant`,`id_user`) values (1,1,5,1,1);
insert into `factors`(`factor_id`,`factor_clean`,`factor_delicious`,`id_restaurant`,`id_user`) values (2,0,5,1,1);
insert into `factors`(`factor_id`,`factor_clean`,`factor_delicious`,`id_restaurant`,`id_user`) values (3,1,5,1,1);
insert into `factors`(`factor_id`,`factor_clean`,`factor_delicious`,`id_restaurant`,`id_user`) values (4,3,3,1,1);
And the result should be like this, Show all ratings (1,2,3,4,5) and their count from the fields rating_clean, rating_delicious, and rating_clean
Thanks for your help.
but the result i get
SELECT COUNT(`factor_clean`+`factor_delicious`),'1' AS rating_1 FROM `factors` WHERE 1 GROUP BY `id_restaurant`
result not should like this
the result should not like that,
my question is, how to select just factor_clean and factor_delicious where factor_clean =1 and factor_delicious = 1
Use union all to unpivot the data and then aggregate:
select id_restaurant, rating, count(*)
from ((select r.id_restaurant, r.rating_clean as rating, r.date
from ratings r
) union all
(select r.id_restaurant, r.rating_delicious, r.date
from ratings r
) union all
(select r.id_restaurant, r.rating_clean2, r.date
from ratings r
)
) r
group by id_restaurant, rating
order by id_restaurant, rating;
For example this is solution for table with colums rating_delicious and rating_clean (only one!):
First of all you should create additional table, I called it factors:
CREATE TABLE `factors` (
`factor_id` int(11) NOT NULL AUTO_INCREMENT,
`factor_clean` int(11) NOT NULL DEFAULT '0',
`factor_delicious` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`factor_id`)
)
Next add two records:
INSERT INTO `factors` (`factor_id`, `factor_clean`, `factor_delicious`) VALUES (NULL, '1', '0'), (NULL, '0', '1');
Now you can join this tables and get results:
SELECT x.id_restaurant
, (x.rating_clean * f.factor_clean) + (x.rating_delicious * f.factor_delicious) AS rating
, count(*)
FROM your_table x
JOIN factors f
WHERE 1
GROUP
BY x.id_restaurant
, rating
In order to use next colum (rating_third), you should and column factor_third to factors, insert new row with 1 in this column and finally add something like your_table.rating_third*factors.factor_third to sum in SELECT

MySQL: Inner Join with Group By is creating a temporary table (doing a table scan)

I've created a query which produces the correct results, yet it is doing a full table scan and creating a temporary table. (Using temporary; Using filesort).
I'd like it to use the indexes, but because I'm using group by to remove duplicates it does not use the indexes which are available. I've tried removing Group By and using Distinct, but this does not solve the problem.
I'm using a many-to-many relationship because an employee can have multiple positions and multiple employees can have the same positions.
Tables:
CREATE TABLE IF NOT EXISTS `Employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(50) DEFAULT NULL,
`middlename` varchar(7) DEFAULT NULL,
`lastname` varchar(50) DEFAULT NULL,
`city` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `firstname` (`firstname`),
KEY `middlename` (`middlename`),
KEY `lastname` (`lastname`),
KEY `city` (`city`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `Employee_Position` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`employee_id` int(11) NOT NULL,
`position_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `employee_id` (`employee_id`),
KEY `function_id` (`position_id`),
KEY `employee_id+position_id` (`employee_id`,`position_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `Positions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Query:
SELECT
e.id,
e.firstname,
e.middlename,
e.lastname,
e.city
FROM Employees AS e
INNER JOIN Employee_Position AS ep
ON e.id = ep.employee_id
WHERE (ep.position_id IN (1, 2, 3, 4))
GROUP BY e.id
ORDER BY e.lastname
Why is this creating a temporary table and not using indexes? And is there any way to fix this?
Your query is doing an aggregation unnecessarily.
Here is a better way to phrase the query:
SELECT e.id, e.firstname, e.middlename, e.lastname, e.city
FROM Employees e
WHERE EXISTS (SELECT 1
FROM Employee_Position ep
WHERE e.id = ep.employee_id AND ep.position_id IN (1, 2, 3, 4)
)
ORDER BY e.lastname;
You already have the right index for this query, on employee_position(employee_id, position_id).

Inner join 3 tables and calculate the average value on a field

There are 3 tables:
medics:
IDM (id_medic) (primary key)
1st name
2nd name
specialty
patients:
IDP (id_patient) (primary key)
name
DOB (date of birth)
visits:
id
id_medic
id_patient
I would like to find out the average age of patients for each specialty.
SELECT specialty, AVG(year(curdate()) - year(patients.DOB))
FROM medics, patients, visits
WHERE medics.IDM = visits.medics GROUP by specialty;
The query above shows me on each line the average of all patients.
Try it:
SELECT
Speciality,
ROUND(AVG(YEAR(NOW())-YEAR(DOB)),0) AS Years
FROM visits
INNER JOIN medics
ON visits.IdMedic = medics.Id
INNER JOIN patients
ON visits.IdPatient = patients.Id
GROUP BY Speciality
My tables:
CREATE TABLE `visits` (
`Id` int(11) NOT NULL,
`IdMedic` int(11) DEFAULT NULL,
`IdPatient` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `patients` (
`Id` int(11) NOT NULL,
`Name` varchar(45) DEFAULT NULL,
`DOB` date DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `medics` (
`Id` int(11) NOT NULL,
`Name` varchar(45) DEFAULT NULL,
`Speciality` varchar(45) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Joining 3+ tables using SQL displaying too many results

im trying to create a query to join these tables together using this method below. However it is repeating results and they are not linking up correctly. as in the same rating comment would be on about 4/5 different results etc. its producing 18ish results when im expecting 3. would anyone be willing to help me with this problem?
SELECT a.Company_name,
f.Job_ID,
f.Job_Name,
b.User_Name,
c.Comments,
c.Reliability,
c.Rating
FROM company a,
Users b,
Ratings c,
UserCompJobRating d,
Company_Job e,
Jobs f
WHERE d.Comp_job_ID = e.Comp_Job_ID
AND b.users_ID = d.users_ID
AND c.Rating_ID = d.Rating_ID;
Many Thanks,
Andrew
ok i tried this and it is saying e.Users_ID is an unknown column in 'on clause'
SELECT a.Company_name,
b.Job_ID,
b.Job_Name,
c.User_Name,
d.Comments,
d.Reliability,
d.Rating
FROM Company a, UserCompJobRating e, Jobs b
INNER JOIN Users c
ON c.Users_ID = e.Users_ID
inner join Company_Job f
on e.Comp_Job_ID = f.Comp_Job_ID
inner join Ratings d
on d.Rating_ID = e.Rating_ID;
I'm assuming im close, however way off at the same time?
Ill try to give you some more information:
UserCompJobRating has a primary key UCJR_ID and 3 foreign keys of Comp_Job_ID, Users_ID and Rating_ID
Company_Job table as a primary key Comp_Job_ID, and 2 foreign keys Job_ID, Company_ID
Ratings Table has just the Rating_ID as a primary key and the rest just to do with the rating information
Users Table has a Users_ID as a primary key and basic user information address etc etc
Jobs Table has a Job_ID primary key and basic information about the job, such as name, price, etc.
Company Table has Company_ID as a primary key and the basic company information, similar to the Users table.
Here are the definations:
CREATE TABLE `company` (
`Company_ID` int(11) NOT NULL AUTO_INCREMENT,
`Company_Name` varchar(45) NOT NULL,
`CAddress` varchar(45) NOT NULL,
`CTown` varchar(45) NOT NULL,
`CPostcode` varchar(12) NOT NULL,
`CTelephone` varchar(45) NOT NULL,
PRIMARY KEY (`Company_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
CREATE TABLE `company_job` (
`Comp_Job_ID` int(11) NOT NULL AUTO_INCREMENT,
`Company_ID` int(11) NOT NULL,
`Job_ID` int(11) NOT NULL,
PRIMARY KEY (`Comp_Job_ID`),
KEY `Company_ID_idx` (`Company_ID`),
KEY `Job_ID_idx` (`Job_ID`),
CONSTRAINT `Company_ID` FOREIGN KEY (`Company_ID`) REFERENCES `company` (`Company_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `Job_ID` FOREIGN KEY (`Job_ID`) REFERENCES `jobs` (`Job_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
CREATE TABLE `jobs` (
`Job_ID` int(11) NOT NULL AUTO_INCREMENT,
`Job_Name` varchar(45) NOT NULL,
`Job_Cost` varchar(45) DEFAULT NULL,
`Job_Avg_Time` varchar(45) DEFAULT NULL,
`Job_Avg_Cost` varchar(45) DEFAULT NULL,
`Job_Description` varchar(45) NOT NULL,
`Company_ID` int(11) NOT NULL,
PRIMARY KEY (`Job_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `ratings` (
`Rating_ID` int(11) NOT NULL AUTO_INCREMENT,
`Comments` varchar(200) DEFAULT NULL,
`Cost` varchar(45) DEFAULT NULL,
`Reliability` varchar(45) DEFAULT NULL,
`Rating` int(11) DEFAULT NULL,
PRIMARY KEY (`Rating_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `usercompjobrating` (
`UCJR_ID` int(11) NOT NULL AUTO_INCREMENT,
`Comp_Job_ID` int(11) DEFAULT NULL,
`Rating_ID` int(11) DEFAULT NULL,
`Users_ID` int(11) DEFAULT NULL,
PRIMARY KEY (`UCJR_ID`),
KEY `Comp_Job_ID_idx` (`Comp_Job_ID`),
KEY `Rating_ID_idx` (`Rating_ID`),
KEY `User_ID_idx` (`Users_ID`),
CONSTRAINT `Comp_Job_ID` FOREIGN KEY (`Comp_Job_ID`) REFERENCES `company_job` (`Comp_Job_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `Rating_ID` FOREIGN KEY (`Rating_ID`) REFERENCES `ratings` (`Rating_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `Users_ID` FOREIGN KEY (`Users_ID`) REFERENCES `users` (`Users_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `users` (
`Users_id` int(11) NOT NULL AUTO_INCREMENT,
`User_Name` varchar(45) NOT NULL,
`UAddress` varchar(45) NOT NULL,
`UTown` varchar(45) NOT NULL,
`UPostcode` varchar(45) NOT NULL,
`UTelephone` varchar(45) NOT NULL,
`UDOB` varchar(45) NOT NULL,
PRIMARY KEY (`Users_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
The query needs to look something like this i.e. use this form
SELECT a.Company_name,
f.Job_ID,
f.Job_Name,
b.User_Name,
c.Comments,
c.Reliability,
c.Rating
FROM company a
INNER JOIN Users b
ON a.???? = b.???
Since I dont have your table definitions I cant help you with the JOIN conditions. Show us the tables definition and we would be able to help.
UPDATE:
So based on your table structures you will be looking for something like this:
SELECT *
FROM company cmp
INNER JOIN company_job cmpjb
ON cmp.Company_ID = cmpjb.Company_ID
INNER JOIN jobs jb
ON cmpjb.Job_ID = jb.Job_ID
INNER JOIN usercompjobrating ucmpjbr
ON ucmpjbr.Comp_Job_ID = ucmpjbr.Comp_Job_ID
INNER JOIN users usr
ON usr.Users_id = ucmpjbr.Users_ID
INNER JOIN ratings rat
ON rat.Rating_ID = ucmpjbr.Rating_ID
Note you cannot use the folder table in this join as there are no primary/foreign key relationships to any of the other tables from the folder table.
I would suggest that you carefully dissect this query and let me know if you need to understand the details.
One thing to clarify, what is company_id in table jobs?
select ... (necessary fields to select)
from company c
join company_job cj using (company_id)
join jobs j using (job_id)
join usercompjobrating ucjr using (comp_job_id)
join ratings using (rating_Id)
join users using (users_id)