How to attain value from the same table - mysql

Now I want to get a comments list, and I have two table named TB_COMMENT, TB_USER;
the TB_COMMENT table has three fields: WORK_ID, USER_ID, ATED_USER_ID;
the TB_USER table has three fields: USER_ID, NICKNAME.
now the front end gives me a workId, and I need to return the list include:
userId, nickname, atedUserId, atedNickname.(and the atedUserId, atedNickname may not exist).
And I just write this sql sentence:
SELECT DISTINCT TB_USER.USER_ID, TB_USER.NICKNAME, TB_COMMENT.ATED_USER_ID
FROM TB_USER, TB_COMMENT
WHERE TB_COMMENT.WORK_ID = #{workId} AND TB_COMMENT.USER_ID = TB_USER.USER_ID`
and I don't know how to get the atedNickname. Hope someone can help me, thanks.

You need one more join with TB_USER on ATED_USER_ID foreign key
SELECT DISTINCT ua.USER_ID, ua.NICKNAME, ub.USER_ID, ub.NICKNAME
FROM TB_USER ua INNER JOIN TB_COMMENT c ON ua.USER_ID = c.USER_ID
LEFT JOIN TB_USER ub ON ub.USER_ID = c.ATED_USER_ID
WHERE c.WORK_ID = #{workId}

Related

Getting values from multiple tables in mysql

I have three tables
user_table:
user_id
user_name
leave_type:
leave_id
leave_name
leave_taken
id
leave_id
applied_by (user_id)
approved_by (user_id)
My end result should be
Result:
leave_name
applied_by (user_name)
approved_by (user_name)
This is what I have tried and got stuck at. I'm sorry for not providing what I tried the first time I posted this question.
Option 1:
SELECT leave_type.leave_name, users.user_name as applied_by,
leaves.no_of_days, leaves.leave_date, leaves.leave_upto_date,
leaves.leave_status
from leaves
join leave_type on leaves.leave_type = leave_type.id
join users on leaves.applied_by = users.id
Option 2:
SELECT leave_type.leave_name, users.user_name as applied_by,
leaves.approved_by, leaves.no_of_days, leaves.leave_date,
leaves.leave_upto_date, leaves.leave_status, leaves.approved_on
FROM leave_type, leaves, users
WHERE leave_type.id = leaves.leave_type
AND leaves.applied_by = users.id
P.S. I'm new to MySQL & I'm not sure how to implement this.
I achieved your desired result with the following query. I'm not very sure if this is the best way though.
SELECT leave_type.leave_name, users.user_name AS applied_by,
(SELECT user_name FROM users WHERE id = leaves.approved_by) AS approved_by,
leaves.no_of_days, leaves.leave_date, leaves.leave_upto_date,
leaves.leave_status
FROM leaves
JOIN leave_type on leaves.leave_type = leave_type.id
JOIN users on leaves.applied_by = users.id;
If you need to join the same table twice, you can provide it with an alias.
In this case, the user table has been joined with two different aliases. I've made the aliases in capitals, so it's easier to find them, but of course, you can write them however you want.
SELECT
leave_type.leave_name,
APPLY_USER.user_name as applied_by,
APPROVE_USER.user_name as approved_by,
leaves.no_of_days, leaves.leave_date, leaves.leave_upto_date,
leaves.leave_status
from leaves
join leave_type on leaves.leave_type = leave_type.id
join users AS APPLY_USER on leaves.applied_by = APPLY_USER.id
join users AS APPROVE_USER on leaves.applied_by = APPROVE_USER.id

Full outer join in mysql with movie database

Hi I have the following tables and columns.
movie: ID, title
person: ID, name
involved: personID, movieID
I need to answer the question:
"Which movies have either John Travolta or Uma Thurman, but not both starred in?"
I couldn't figure out how to do this without creating new tables, so I made 2 new tables. And tried to do the full outer join on, where you dont get intersecting results. I found out that you can't do full outer joins in mysql but had to do a left join, unioned with a right join. I tried this but don't get the results I wanted at all. I have been stuck for a while now. Can anyone point me in the right direction?
This is what I have so far.
DROP TABLE IF EXISTS Umatable;
DROP TABLE IF EXISTS Johntable;
CREATE TABLE Umatable(title VARCHAR(500));
CREATE TABLE Johntable(title VARCHAR(500));
INSERT INTO Umatable
SELECT m.title
FROM movie m, person p, involved i
WHERE p.name = "Uma Thurman"
AND p.id = i.personid
AND m.id = i.movieiD;
INSERT INTO Johntable
SELECT m.title
FROM movie m, person p, involved i
WHERE p.name = "John Travolta"
AND p.id = i.personid
AND m.id = i.movieiD;
SELECT *
FROM Umatable
LEFT JOIN Johntable ON Umatable.title = Johntable.title
WHERE Johntable.title IS NULL OR Umatable.title IS NULL
UNION
SELECT *
FROM Umatable
RIGHT JOIN Johntable ON Umatable.title = Johntable.title
WHERE Johntable.title IS NULL OR Umatable.title IS NULL
I would do this using aggregation and having:
select i.movieId
from involved i join
person p
on p.id = i.personId
group by i.movieId
having sum(p.name in ('John Travolta', 'Uma Thurman')) = 1;
A count(*) inside a correlated subquery will work:
select *
from movie m
where 1 = (select count(*)
from involved i
join person p
on p.ID = i.personID
and p.name IN ('John Travolta', 'Uma Thurman')
where i.movieID = m.ID)
SQLFiddle Demo

better way of doing this SELECT in MySQL

Best way to do this SELECT?
I've got this tables:
t_department
id
name
t_users
id
name
type
*type can be:
1 SuperUser
2 normalUser
t_department_superuser
(A department can have many superUsers)
-idSuperUser
-idDepartment
t_superuser_normaluser
(A superUser can have many normalusers)
-idSuperUser
-idNormalUser
and finally
t_actions
-id (autonumeric)
-idUser (this can be an id of superUser or normalUser)
-action
Given a department name, for example "mainDepartment"
I need to get all records from t_actions of all normalusers and all superusers of that department
I have this, it works, but I am not an SQL expert (I am using MySQL) and I think it is not the best way to do the select, and t_actions is going to have loads of rows:
SELECT id,idUser,action
FROM t_actions
WHERE (idUser IN (
SELECT DISTINCT t_department_superuser.idSuperUser FROM t_department
RIGHT JOIN t_department_superuser ON t_department_superuser.idDepartment = t_department.id
LEFT JOIN t_superuser_normaluser ON t_superuser_normaluser.idSuperUser = t_department_superuser.idSuperUser
WHERE name='mainDepartment'
UNION ALL
SELECT DISTINCT t_superuser_normaluser.idNormalUser
FROM t_department
RIGHT JOIN t_department_superuser ON t_department_superuser.idDepartment = t_department.id
LEFT JOIN t_superuser_normaluser ON t_superuser_normaluser.idSuperUser = t_department_superuser.idSuperUser
WHERE name='mainDepartment')
ORDER BY id;
Any suggestions to make this better? thank you!!
because you are using left and right joins there will be null records, which is why you need the UNION... you can cut out the UNION with a simple null check
SELECT id, idUser, action
FROM t_actions
WHERE idUser IN
( SELECT DISTINCT COALESCE(tsn.idNormalUser, tds.idSuperUser)
FROM t_department td
RIGHT JOIN t_department_superuser tds ON tds.idDepartment = td.id
LEFT JOIN t_superuser_normaluser tsn ON tsn.idSuperUser = tds.idSuperUser
WHERE td.name='mainDepartment'
)
ORDER BY id;
note i also added alias's to your table names so its easer to write out and read the columns you are trying to select and join on.
EDIT
with the data the only possible way to do it with this table design is like this
SELECT id, idUser, action
FROM t_actions
WHERE idUser IN
((SELECT tds.idSuperUser
FROM t_department td
JOIN t_department_superusers tds ON tds.idDepartment = td.id
WHERE td.name='MAIN')
UNION
(SELECT tsn.idNormalUser
FROM t_department td
JOIN t_department_superusers tds ON tds.idDepartment = td.id
JOIN t_superuser_normaluser tsn ON tsn.idSuperUser = tds.idSuperUser
WHERE td.name='MAIN')
)
ORDER BY id;

SQL join multiple times?

I am making a user status list of the following format "A like B's XXX". A and B are both registered users and have firstname and lastname and user id. How to join the status table with the user table twice to get the names of the two users? Thank you.
SELECT "SQACTION"."TIMECREATED",
"SQWORDLIST".*,
"SUBJECT"."FIRSTNAME" subject_fn,
"SUBJECT"."LASTNAME" subject_ln,
author.firstname author_fn,
author.lastname author_ln
FROM "SQACTION"
INNER JOIN "SQWORDLIST"
ON SQACTION.ACTION = SQWORDLIST.GUID
INNER JOIN "SQUSER" SUBJECT
ON SQACTION.SUBJECT = SUBJECT.GUID
LEFT JOIN SQDOCUMENT
ON SQACTION.ENTITY = SQDOCUMENT.GUID
LEFT JOIN SQUSER AUTHOR
ON SQDOCUMENT.AUTHORID = AUTHOR.GUID
WHERE (SUBJECT.GUID = 'B4D3BF632C0C4DB3AB01C8B284069D8F')
OR (SUBJECT.GUID IN ('67882AF3FA3C4254AF9A12CA0B0AB6E4',
'6A4B52FE233444838AACFE2AFFE4D38F',
'8CA3FB9061FF4710B51F1E398D3D1917'))
ORDER BY "TIMECREATED" DESC
This is what I have tried. Thank you.
You need to include the table name twice in the FROM clause, and use an alias so you can specify which fields from each instance of the table are used in the ON statement. You didn't provide enough details in your question to give an exact example, so here is something more general.
UserTable, with ID & Name
RegTable, with UserID, and SponsorID
select ut1.name as [User],
ut2.name as [Sponsor]
from UserTable ut1
inner join RegTable rt on ut1.id = rt.userid
inner join UserTable ut2 on rt.sponsorid = ut2.id
do you mean something like, status have two field links to user table?
select user_a.first_name as user_a_first_name, user_b.first_name as user_b_first_name, status.status_name
from status
left join users as user_a on user_a.id = status.user_from_id
left join users as user_b on user_b.id = status.user_to_id

SQL Select multiple column values

I'm having difficulty with some SQL - and finding it hard to describe so please bear with me. I'm trying to select products that have an x number of correct features. To simplify things, the problem I'm having is with a few tables. The relevant information about my tables, is:
products(**product_id**)
features(**feature_id, product_id**, value_id)
featurenames(**feature_id**, name)
featurevalues(**value_id**, value)
I am trying to select all products that, for example, are for sex:male age:children, with age and sex being names in the featurenames table and male and children being values in the featurevalues table. This is part of another bigger query that gets all the products by category, which I haven't included as it will just complicate things. Thank you for your help in advance.
It's the table so nice, you join to it twice.
Select
P.Product_ID
From
Products P
Inner Join Features F1 On P.Product_ID = F1.Product_ID
Inner Join FeatureNames FN1 On F1.Feature_ID = FN1.Feature_ID And FN1.Name = 'sex'
Inner Join FeatureValues FV1 On F1.Value_ID = FV1.Value_ID And FV1.Value = 'male'
Inner Join Features F2 On P.Product_ID = F2.Product_ID
Inner Join FeatureNames FN2 On F2.Feature_ID = FN2.Feature_ID And FN1.Name = 'age'
Inner Join FeatureValues FV2 On F2.Value_ID = FV2.Value_ID And FV1.Value = 'children'