How to Fix This MySQL Query So It Works? - mysql

I have the following query:
UPDATE lessonstatus
INNER JOIN user ON lessonstatus.user_id = user.user_id
SET user_id = (SELECT user_id FROM user WHERE username = 'too_many_accounts')
WHERE last_name = 'stupid'
AND first_name = 'user'
AND username != 'too_many_accounts'
AND lessonstatus.lesson_id NOT IN (SELECT lesson_id FROM lessonstatus WHERE user_id = 1);
However, I get the following error when trying to execute it:
Error Code : 1093
You can't specify target table 'lessonstatus_rtab' for update in FROM clause
How would I fix this query so that it works?

You can't SELECT from a table (even in a subquery) that you're updating in the same query. That's what the error "can't specify target table" means.
But you can join user and lessonstatus multiple times in the UPDATE statement, and use the join criteria creatively to pick out the individual row you want.
The way to simulate NOT IN with a join is to do a LEFT OUTER JOIN. Where the right side of that join is not matched, that's where NOT IN would be true.
UPDATE lessonstatus l1
INNER JOIN user u1 ON (l1.user_id = u1.user_id)
INNER JOIN user u2 ON (u2.username = 'too_many_accounts')
LEFT OUTER JOIN lessonstatus l2
ON (l1.lesson_id = l2.lesson_id AND l2.user_id = 1)
SET l1.user_id = u2.user_id
WHERE u1.last_name = 'stupid' AND u1.first_name = 'user'
AND u1.username != 'too_many_accounts'
AND l2.lesson_id IS NULL; -- equivalent to "l NOT IN l2"
nb: I have tested this query for syntax, but not with real data. Anyway, it should get you started.

There are more errors ("user" table and "user_rtab" alias do not match, use of non-qualified field names is not recommended), but UPDATE syntax itself should be similar:
UPDATE lessonstatus
SET user_id = (SELECT TOP 1 user_id FROM user WHERE username = 'too_many_accounts')
FROM lessonstatus
INNER JOIN user ON lessonstatus.user_id = user_rtab.user_id
WHERE last_name = 'stupid'
AND first_name = 'user'
AND username != 'too_many_accounts'
AND lessonstatus.lesson_id NOT IN (
SELECT lesson_id FROM lessonstatus WHERE user_id = 1
);

Related

how to grab the not equal row from joined table in mysql?

i have two tables as following
user_job_applied
company_viewed_user
i want to take rows which are not in company_viewed_user table for relevant job_id in user_job_applied table.
i wrote the following query for it but it's not grabbed
SELECT
`user_job_applied`.user_id
FROM
`user_job_applied`
LEFT JOIN
`company_viewed_user`
ON
`company_viewed_user`.user_id ON `company_viewed_user`.user_id = `user_job_applied`.user_id
WHERE
`company_viewed_user`.user_id IS NULL AND
`company_viewed_user`.emp_id IN (SELECT user_id
FROM company_user
WHERE company_id='1')
AND
`user_job_applied`.job_id = '1';
The output should be as following
want to move emp_id condition to left join statement from in where clause
SELECT
`user_job_applied`.user_id
FROM
`user_job_applied`
LEFT JOIN `company_viewed_user` ON `company_viewed_user`.user_id = `user_job_applied`.user_id AND
`company_viewed_user`.emp_id IN (SELECT user_id FROM company_user WHERE company_id='1')
WHERE
`company_viewed_user`.user_id IS NULL AND
`user_job_applied`.job_id = '1';
You can use below query
SELECT uja.user_id
FROM `user_job_applied` AS uja
LEFT JOIN `company_viewed_user` AS cvu ON cvu.user_id = uja.user_id
WHERE cvu.user_id IS NULL;
If you want to add any other filter then you can include your own or let me know.
Added new conditions
SELECT uja.user_id
FROM `user_job_applied` AS uja
JOIN company_user AS cu ON cu.user_id=uja.emp_id
LEFT JOIN `company_viewed_user` AS cvu ON cvu.user_id = uja.user_id
WHERE uja.job_id=1 AND cu.company_id=1 AND cvu.user_id IS NULL;
Note: If job_id and company_id is not Int type then enclosed in quotes.

Selecting data for 1 specific user from multiple tables

So my database is composed of 5 tables with different columns for each one. The only column that keeps them all identified is the id. I'm trying to get the data for a specific user, but I only seem to get all users of the database instead.
This is what I have tried:
SELECT
ControlAccess.UserName,
ControlAccess.Pass,
Users.First_Name,
Users.Last_Name,
UserInfo.Age,
UserInfo.Country,
UserInfo.Address,
UserInfo.ZipCode,
Sessions.Matrix1,
Sessions.Matrix2,
Sessions.Result,
Operations.Operation,
FilePath.LocationFiles
FROM
MatrixUsers.UserInfo
INNER JOIN
MatrixUsers.Users
ON
UserInfo.idUserInfo = Users.idUsers = 1
INNER JOIN
MatrixUsers.ControlAccess
ON
ControlAccess.idControlAccess = UserInfo.idUserInfo = 1
INNER JOIN
MatrixUsers.Sessions
ON
Sessions.idSessions = ControlAccess.idControlAccess = 1
INNER JOIN
MatrixUsers.FilePath
ON
FilePath.idFilePath = Sessions.idSessions = 1
INNER JOIN
MatrixUsers.Operations
ON
Operations.idOperations = FilePath.idFilePath = 1;
I tried putting 1 at the end of each id to see if they matched, but I still get all the users.
I'm new to SQL and I'm only familiar with matching rows, but not choosing specific one.
Here are the columns of each table:
ControlAccess: {idControlAccess, UserName, Pass}
Sessions: {idSessions, Matrix1, Matrix2, Result}
FilePath: {idFilePath, LocationFiles}
Operations: {idOperation, Operation}
UserInfo: {idUserInfo, Age, Country, Address, ZipCode, Phone}
Use WHERE when you want specific user. for example, select user_id from table where user_id=the_specific_user_id . Follow this basic to built you complicate statement.
Just user where after all the joins
WHERE ANY_COLUMN_REFER_TO_USER_ID = YOUR_NEEDED_ID
so your full query would be like :
SELECT
ControlAccess.UserName,
ControlAccess.Pass,
Users.First_Name,
Users.Last_Name,
UserInfo.Age,
UserInfo.Country,
UserInfo.Address,
UserInfo.ZipCode,
Sessions.Matrix1,
Sessions.Matrix2,
Sessions.Result,
Operations.Operation,
FilePath.LocationFiles
FROM MatrixUsers.UserInfo
INNER JOIN MatrixUsers.Users
ON UserInfo.idUserInfo = Users.idUsers
INNER JOIN MatrixUsers.ControlAccess
ON ControlAccess.idControlAccess = UserInfo.idUserInfo
INNER JOIN MatrixUsers.Sessions
ON Sessions.idSessions = ControlAccess.idControlAccess
INNER JOIN MatrixUsers.FilePath
ON FilePath.idFilePath = Sessions.idSessions
INNER JOIN MatrixUsers.Operations
ON Operations.idOperations = FilePath.idFilePath
WHERE UserInfo.idUserInfo = 1

JPQL: Update if not exists

I'm trying to achieve something like this in may JPA/Hibernate/MySQL application:
UPDATE UserRating ur SET ur.item = :newItem WHERE ur.item = :oldItem AND NOT EXISTS (SELECT ur2 FROM UserRating ur2 WHERE ur.user = ur2.user AND ur2.item = :newItem)
So, I want to update some rows only if they will be unique (user/item combination must be unique).
I'm getting
Caused by: java.sql.SQLException: You can't specify target table 'user_rating' for update in FROM clause
with the current JPQL.
One way is to turn in it into JOIN
UPDATE UserRating r JOIN
(
SELECT user, item
FROM UserRating ur
WHERE item = :oldItem
AND NOT EXISTS
(
SELECT *
FROM UserRating
WHERE user = ur.user
AND item = :newItem
)
) q ON r.user = q.user
AND r.item = q.item
SET r.item = :newItem
Here is SQLFiddle demo

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

How to use MYSQL's "AS" returned value inside WHERE clause?

I have a query like below...
SELECT
contents.id, contents.title, contents.createdBy,
(SELECT userGroup FROM suser_profile WHERE userId =
(SELECT users.id
FROM
users
WHERE
login = contents.createdBy)
) as userGroupID
FROM
contents
WHERE
contents.id > 0
AND contents.contentType = 'News'
**AND userGroupID = 3**
LIMIT 0, 10
When I try to assign the userGroupID inside WHERE clause the SQL fires an error saying SQL Error(1054):Unknown column "userGroupID" in "where clause"
meantime, if I make little changes like below,,
SELECT
contents.id, contents.title, contents.createdBy
FROM
smart_cms_contents
WHERE
contents.id > 0
AND contents.contentType = 'News'
**AND (SELECT userGroup FROM user_profile WHERE userId =
(SELECT users.id
FROM
users
WHERE
users.login = contents.createdBy)
) = 3**
LIMIT 0, 10
then the query works fine.
I have to use multiple userGroupID checking so that, 2nd style will make the query big, I have to have an style like first one, any help appreciated.
*NOTE : Table names are not original name what I am using in my project. You may ignore it if there are mistakes in table name. My main concern is on using the values assign to a variable by AS inside the WHERE clause.
Ignore the STARS in query*
use HAVING. example:
WHERE
contents.id > 0
AND
contents.contentType = 'News'
HAVING
userGroupID = 3
LIMIT 0, 10
If I'm understanding your initial query properly, then I believe what you want to do is a join:
SELECT DISTINCT
contents.id, contents.title, contents.createdBy
FROM
contents INNER JOIN users
ON contents.createdBy = users.login
INNER JOIN user_profile
ON user_profile.userId = users.id
WHERE
contents.id > 0
AND contents.contentType = 'News'
AND user_profile.userGroupID = 3
LIMIT 0, 10
Totally not the answer to the question you asked, but...
SELECT DISTINCT c.id, c.title, c.createdBy, s.userGroup AS userGroupID
FROM contents AS c
INNER JOIN users AS u
ON c.createdBy = u.login
INNER JOIN suser_profile AS s
ON s.userId = u.id
WHERE c.id > 0
AND c.contentType = 'News'
AND s.userGroup = 3