mysql like and different value not working - mysql

I'm doing a form of research every things work fine except the clause <> i don't know why happen. any help?
this is my query
SELECT users . * , image_upload.name_image
FROM users
LEFT JOIN image_upload ON users.profile_image = image_upload.id_image
WHERE users.id <>1
AND LOWER( users.name ) LIKE 'f%'
OR LOWER( users.surname ) LIKE 'f%'
LIMIT 5
when start the query, it shows the row with the id = 1 logically is not correct.

Try this:
SELECT users . * , image_upload.name_image
FROM users
LEFT JOIN image_upload ON users.profile_image = image_upload.id_image
WHERE users.id <>1
AND (LOWER( users.name ) LIKE 'f%'
OR LOWER( users.surname ) LIKE 'f%')
LIMIT 5
Remember that the OR statement really has to be in parenthesis due to the way that operators are processed.
Here's a link for you:
http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html

Related

How to select a number of logins by a MySQL query?

I would like to select all login events and also the number of logins under one specific IP address by a MySQL query.
The Query that I have come up with is as follows. But I am afraid I have been missing something.
Hopefully one can see my mistake.
SELECT `pp_loginevent`.`loginevent_user`,
`pp_loginevent`.`loginevent_creationdate`,
`pp_loginevent`.`loginevent_ip`,
`pp_user`.`user_id`,
`pp_user`.`user_name`,
`pp_user`.`user_rights`,
`pp_user`.`user_active`,
`pp_license`.`license_name`
(SELECT COUNT(1)
FROM `pp_loginevent`
WHERE `loginevent_ip` = `pp_loginevent`.`loginevent_ip`
) AS `pp_loginevent`.`number_of_logins`
FROM `pp_loginevent`
LEFT JOIN `pp_user`
ON `pp_loginevent`.`loginevent_user` = `pp_user`.`user_id
LEFT JOIN `pp_license`
ON `pp_loginevent`.`loginevent_license` = `pp_license`.`license_id`
WHERE `loginevent_creationdate` LIKE '2019-%'
AND `user_rights` <= '6'
GROUP BY `loginevent_ip`
ORDER BY `loginevent_creationdate` DESC
What I am trying to do is to fetch the "column" number_of_logins and that should contain the number of logins made from a specific IP address.
You can't see anything wrong here:
`pp_license`.`license_name`
(SELECT COUNT(1) FROM `pp_loginevent` WHERE `loginevent_ip` = `pp_loginevent`.`loginevent_ip`) AS `pp_loginevent`.`number_of_logins`
?
While this won't resolve all the problems with this query, I think writing the query out this way makes one error very obvious:
SELECT e.loginevent_user
, e.loginevent_creationdate
, e.loginevent_ip
, u.user_id
, u.user_name
, u.user_rights
, u.user_active
, l.license_name
(SELECT COUNT(1)
FROM pp_loginevent
WHERE loginevent_ip = pp_loginevent.loginevent_ip) pp_loginevent.number_of_logins
FROM pp_loginevent e
JOIN pp_user u
ON u.user_id = e.loginevent_user
LEFT
JOIN pp_license l
ON l.license_id = e.loginevent_license
WHERE e.loginevent_creationdate >= '2019-01-01'
AND e.loginevent_creationdate < '2020-01-01'
AND user_rights <= 6
GROUP
BY loginevent_ip
ORDER
BY loginevent_creationdate DESC
In truth, as well as this syntax error, I suspect that there are other, logical, errors in this query.
Accordingly, see: Why should I provide an MCRE for what seems to me to be a very simple SQL query?

SQL query that limits the results to one when using count inside count

I am trying to select the count of likes on a specific project. The idea i came up with is
CAST(count(uploads.ID in (SELECT uploadID from votes)) as decimal) as numberoflikes
this works but the query then only returns one thing.
Entire query
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,subjects.NAME AS subjectname
,uploads.TIME
,uploads.description
,uploads.NAME
,uploads.ID
,CASE
WHEN uploads.ID IN (
SELECT uploadID
FROM votes
WHERE userID = 2
)
THEN CAST(1 AS DECIMAL)
ELSE CAST(0 AS DECIMAL)
END AS liked
,CASE
WHEN uploads.ID IN (
SELECT uploadID
FROM bookmarks
WHERE userID = 2
)
THEN CAST(1 AS DECIMAL)
ELSE CAST(0 AS DECIMAL)
END AS bookmarked
,CAST(count(uploads.ID IN (
SELECT uploadID
FROM votes
)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN subjects ON (subjects.ID = uploads.subjectID)
INNER JOIN users ON (users.ID = uploads.userID)
INNER JOIN uploadGrades ON (uploads.ID = uploadGrades.uploadID)
INNER JOIN grades ON (grades.ID = uploadGrades.gradeID)
WHERE uploads.active = 1
AND subjects.ID IN (
SELECT subjectID
FROM userSubjects
INNER JOIN users ON (users.ID = userSubjects.userID)
WHERE userSubjects.userID = 2
)
AND grades.ID IN (
SELECT userGrades.gradeID
FROM uploadGrades
INNER JOIN userGrades ON (uploadGrades.gradeID = userGrades.gradeID)
WHERE userGrades.userID = 2
)
ORDER BY uploads.trueRating DESC;
Lets try a reduce version of your query, That is the base to get better answers
I reduce the initial query to user and upload to start. Also remove the fields you already know how to calculate.
.
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,uploads.NAME
,uploads.ID
,CAST(count(uploads.ID IN (
SELECT uploadID
FROM votes
)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN users ON (users.ID = uploads.userID)
WHERE uploads.active = 1
ORDER BY uploads.trueRating DESC;
Then add votes with LEFT JOIN to replace the SELECT in the COUNT that way if not match you will get NULL and as I say in my comment COUNT doesnt count NULL's
.
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,uploads.NAME
,uploads.ID
,CAST(count(votes.uploadID)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN users ON (users.ID = uploads.userID)
LEFT JOIN votes ON (uploads.ID = votes.uploadID)
WHERE uploads.active = 1
ORDER BY uploads.trueRating DESC;
Try something like this...
SELECT users.name as username, users.ID as userID, subjects.name as subjectname,
uploads.time, uploads.description, uploads.name, uploads.ID,
count(userVotes.userId), count(bookmarksMade.userId),
FROM uploads
join subjects on(subjects.ID = uploads.subjectID)
join users on(users.ID = uploads.userID)
join uploadGrades on(uploads.ID = uploadGrades.uploadID)
join grades on(grades.ID = uploadGrades.gradeID)
left join (select userId, uploadId from votes where userId = 2) as userVotes on uploads.id = userVotes.uploadId
left join (select userId, uploadId from bookmarks where userId = 2) as bookmarksMade on uploads.id = bookmarksMade.uploadId
join userSubjects on subjects.id = userSubjects.subjectID
WHERE uploads.active = 1 AND
userSubjects.userID = 2
ORDER BY uploads.trueRating DESC;
But, I am leaving out the userGrades thing, because you are doing a funky join there that I don't really understand (joining two tables on something that looks like it is not the whole primary key on either table).
Anyway, you really need to go to something more like this or what Oropeza suggests in his answer. Get more direct about what you want. This query looks like a monster that has been growing and getting things added in with "IN" clauses, as you needed them. Time to go back to the drawing board and think about what you want and how to get at it directly.
count(uploads.ID in (SELECT uploadID from votes)) as numberoflikes
group by uploads.Id ORDER BY uploads.trueRating DESC
I managed to do it like this. If i added the group by then it split the numberoflikes into rows and returned more then one row. Thanks for the help!

Use Sql Join two times on a single table

This is my query in 3 Nested form. What i want is to re-write this query using JOINS but the problem is same table is repeating two times as you can see.
$query = "
SELECT
*
FROM userinfo
WHERE id IN (
SELECT DISTINCT
iduser
FROM u_n_relation
WHERE idnetwork IN (
SELECT
idnetwork
FROM u_n_relation
WHERE iduser = '$userid'
)
)
AND virtual_name LIKE CONCAT('%', ?, '%')
ORDER BY id LIMIT 5
"
What i tried was this :
$query = "
SELECT
userinfo.*
FROM userinfo
INNER JOIN u_n_relation ON (u_n_relation.iduser = userinfo.id)
WHERE
(userinfo.virtual_name LIKE CONCAT('%', ?, '%')
AND u_n_relation.iduser = '$iduser')
ORDER BY userinfo.id LIMIT 5
"
But still not getting the correct result.
Can anyone please shed some light on how to do this?
Basically what the query says is :
Fetch the details of the users who have joined the networks you have joined.
select distinct is not needed when you use in. However, it may be needed when you use join. Otherwise you can turn the ins into inner joins:
SELECT ui.*
FROM userinfo ui JOIN
(SELECT DISTINCT unr.iduser
FROM u_n_relation unr JOIN
u_n_relation unr2
ON unr.idnetwork = unr2.idnetwork and
unr2.iduser = '$userid'
WHERE unr.virtual_name LIKE CONCAT('%', ?, '%')
) unr
ON ui.id = unr.iduser
ORDER BY id
LIMIT 5;
Firstly, Mark L. is correct in that aliases are the key to JOINing the same table multiple times in a query.
Secondly, holy crap formatting. Formatting is especially important when posting your query to ask a question about it. Your formatting caused Gordon L. to mis-read which table the "virtual_name" field was in.
Initially your first query didn't make sense to me but jackkorbins comment got me to view it again and I get it this time - here it is formatted more read-ably:
SELECT *
FROM
userinfo
WHERE
id IN (-- This sub-query returns *any* iduser that is a member
-- of those same networks
SELECT DISTINCT
iduser
FROM
u_n_relation
WHERE
idnetwork IN (-- This sub-query returns the multiple networks
-- that have $userid as a member
SELECT
idnetwork
FROM
u_n_relation
WHERE
iduser = '$userid'))
AND virtual_name LIKE CONCAT('%', ?, '%')
ORDER BY
id
LIMIT 5
So another way to make a JOIN version of that query would look like:
SELECT DISTINCT
ui.*
FROM
u_n_relation unr
INNER JOIN u_n_relation net
ON (net.idnetwork=unr.idnetwork)
INNER JOIN userinfo ui
on ( ui.id = net.iduser )
WHERE
unr.iduser = '$iduser'
and ui.virtual_name LIKE CONCAT('%', ?, '%')
ORDER BY
ui.id
LIMIT 5
Sorry for my earlier confusion. :-)

Search for at least 1 hit, mysql and join

i have the following sql query
SELECT
vmm_user.username,
vmm_songs.*,
vmm_albums.desc,
vmm_albums.release,
vmm_albums.name,
AVG(vmm_songrating.rating) AS ratingavg,
COUNT(vmm_songrating.id) AS ratingcount
FROM
vmm_songs
LEFT JOIN
vmm_user
ON
vmm_songs.userid=vmm_user.id
LEFT JOIN
vmm_albums
ON
vmm_songs.albumid=vmm_albums.id
LEFT JOIN
vmm_songrating
ON
vmm_songs.id=vmm_songrating.songid
GROUP BY
vmm_songs.id
HAVING
COUNT(vmm_songrating.id) >= 2
ORDER BY
AVG(vmm_songrating.rating) DESC
LIMIT
10
this works fine but now i have to know if a user already voted for a song and thats my problem
the rating table looks like this
id|songid|userid|rating
i tried something like this
SELECT
...
COUNT(vmm_songrating.id) as hasvoted
...
OUTER JOIN
vmm_songrating
ON
vmm_songrating.userid = $id
...
$id is the user session id
but it doesnt work :/
you can try adding something like this to the selected fields
SUM(case when vmm_songrating.userid = $id then 1 end) as hasvoted

MySQL - very complicated random row

I've got my tables posts and user_unread_posts.
In posts, all the posts of a forum are saved, and in user_unread_posts all posts are saved which are read by a user.
user_undread_postslooks like this:
id uid pid
Now I want to allow users to open a random post which they haven't read. I've tried something like
SELECT * FROM posts
LEFT JOIN user_unread_posts uup
ON uup.pid=posts.id
WHERE uup.uid<>1
ORDER BY RAND()
LIMIT 1
(Whilst 1 is a placeholder UID)
But it doesn't work, like it should work, it return posts too, which are read... How can I fix that?
SELECT *
FROM posts
WHERE id NOT IN
(
SELECT pid
FROM user_unread_posts uup
WHERE uid = $myuserid
)
ORDER BY
RAND()
LIMIT 1
You wanted to use IS NULL with the LEFT JOIN. Using <> turns the LEFT JOIN into an INNER JOIN because NULL can never match the <> operator.
Here is a corrected query:
SELECT * FROM posts
LEFT JOIN user_unread_posts uup
ON uup.pid=posts.id
WHERE uup.uid IS NULL
ORDER BY RAND()
LIMIT 1