MySQL Complex query not returning right results - php

I have the following query:
'SELECT * FROM posts LEFT JOIN taxi ON taxi.taxiID = posts.postID
WHERE (taxi.value = 1 AND taxi.userID ='.$userID.')
AND ??????????????
ORDER BY taxi.ID DESC
LIMIT 10'
The way the site works is the user can tag posts as being "liked". When a post is liked, the taxi table is given a new row with taxiID being the same as postID, userID to store the user that liked the post, and value which is set to 1. Disliking a post sets value to 0.
I want to display all posts where value is 1 and userID is $userID - check. However, I also want the query to display all the posts where the user hasn't liked a post yet. Thing is, if the user hasn't liked a post yet, userID is NULL with a corresponding value of NULL. If I query for that, I'll be skipping those posts that other users have liked but the user hasn't.
Here's the taxi table:
ID taxiID userID value
1 1 1 1
2 1 6 1
3 1 4 0
4 2 1 0
5 2 6 1
6 2 4 0
7 3 6 1
8 3 4 0
Assuming $userID is 1, my query ought to display taxiID 1 and 3 (because user 1 liked ID 1 AND hasn't liked or disliked taxiID 3.
The code I've posted will only result in displaying taxiID 1.
The question is, what is my missing line in my query supposed to be given the above?

It seems you want to find all taxiID that the use has not disliked:
SELECT taxiID
FROM taxi
GROUP BY taxiID
HAVING taxiID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
ORDER BY taxiID DESC
LIMIT 10
Test in SQL-Fiddle
You probably have a post table, so it would be better to use:
SELECT * --- whatever columns from `post` table
FROM post
WHERE postID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
ORDER BY postID
LIMIT 10
If that taxi.taxiID means postID, then you should rename it to taxi.postID. It's very confusing as it is.

I had this as a comment, but I think it's my final answer:
SELECT * FROM posts
LEFT JOIN taxi ON taxi.taxiID = posts.postID
WHERE (taxi.value != 0 AND taxi.userID ='.$userID.')
OR taxi.value is null
ORDER BY taxi.ID DESC
LIMIT 10
Ok, this is what should happen with the above query:
Get all posts
Add the info from the taxi table, and associate taxi data with post data by postID
Only show if taxi.value isn't 0 (meaning it can be null or 1) AND if the userID is the same as our variable

Assuming taxi.taxiID is the same as post.ID and you're looking to select all posts not tagged by a user yet, try:
SELECT * FROM post WHERE ID NOT IN
(SELECT taxiID FROM taxi WHERE userID = 1)
this is for user with an ID=1 of course.

Related

Order by a columns count where another column has a static value

I have a table which stores user items, the two key columns which I would like to use in this query are user_id and item_id. The id field in the example is not needed but just added to show these aren't the only two columns in the table.
----------------------
id user_id item_id
----------------------
1 1 324
2 1 324
3 3 324
4 2 230
5 4 324
The query which I would like to construct should return the top 10 users who have the most items with a specific item id.
So for example if I wanted to run the query against the item ID 324 I should get the following result.
-------------------
user_id item_count
-------------------
1 2
3 1
4 1
2 0
try this
select user_id , count(*) as item_count from table
where item_id = 324 group by user_id order by item_count desc limit 10
limit 10 will show you the top 10 users and order by desc sort from high to low.
However, the above query will not give you the 0 count as per your question. If you really want the zero count you can try this: (assuming your table name is userlist)
SELECT distinct user_id,
(select
count(*) from `userlist`
where user_id=u.user_id and item_id=324
) as item_count FROM `userlist` u
order by item_count desc
I couldn't create the database in my local, but I think this will do the trick
SELECT user_id, COUNT(item_id) as item_count
FROM TABLE_NAME
WHERE item_id = 324
GROUP BY item_id
ORDER BY item_count;

PHP&SQL select highest score

I'm going to select the highest result in my "quiz" table there is 5 type of data:
quizid, userid, quizdate, result, topicid
1 JAKE 1/7/2015 60 1
2 JAKE 1/7/2015 80 1
3 JAKE 1/7/2015 100 2
i wanna show each topic and user highest score only once.
But it only show the first highest score from the user, after user redo the quiz again it wont show the highest score.
Example: Userid JAKE has done first time quiz have 60 mark at quiz 1, when he redo quiz 1 and get 80 marks it still show 60mark at the Table.
Select userid,topicid, MAX(result) as result
FROM quiz GROUP BY userid, topicid
ORDER BY result desc
The final result should be show 80 for JAKE at topic 1, but my result was
1 JAKE 1/7/2015 60 1
3 JAKE 1/7/2015 100 2
Hey you should used it like. if you want complete record with max result
select * from (Select userid,topicid, result as result
FROM quiz ORDER BY result desc) as t GROUP BY t.userid, t.topicid
Try following,
Select userid, topicid, result from
(
Select
row_number() over (order by userid, topicid, result desc) row_id,
userid,
topicid,
result
FROM quiz
) t
where row_id = 1

" People Who Liked this Also Liked " Query in Mysql PHP

Music table
id | title
1 Rap God
2 Blank Space
3 Bad Blood
4 Speedom
5 Hit 'em up
Like table
u_id | m_id
1 1
1 2
1 4
1 5
2 3
2 4
2 5
3 1
3 5
4 1
4 2
4 5
Now if someone visits music with m_id = 1
Then the output might be like
m_id
5
2
4
To explain this a bit...
As m_id = 1 is liked by users -> {1,3,4} which in turn likes ->{2,4,5} musics. Since m_id=5 is liked by max number of users its first followed by m_id = 2 and m_id = 4.
My Try
I queried the users who liked m_id = 1
SELECT u_id FROM likes WHERE m_id =1
Then i stored in in an array and selected each of their likes and
arranged them in desc order of count.
But it is a very slow and long process is there any way i can do this ?
p.s I have heard of Association Rules and Bayesian theorem can be user to achieve this. But can anyone help me out with an example ?
You can JOIN back on the Like table and do something like this.
SELECT also_like.m_id, COUNT(also_like.m_id)
FROM [like] AS did_like
JOIN [like] AS also_like ON
also_like.u_id = did_like.u_id
AND also_like.m_id != did_like.m_id
WHERE did_like.m_id = 1
GROUP BY also_like.m_id
ORDER BY COUNT(also_like.m_id)
Essentially you are getting a list of users who liked an item then getting a complete list of those user's likes excluding the item they just liked.
You can then add a HAVING clause or LIMIT to filter things down a bit more.
using a subquery ...
SELECT m_id, count(u_id) as Rank FROM `like`
WHERE u_id in
(
SELECT u_id
FROM `like`
WHERE m_id = 1
)
AND m_id <> 1
GROUP BY m_id
ORDER BY Rank DESC
and optionally
LIMIT 0, 10
or how many "alsolikes" you want to display

Count likes of the latest date per user

I have a table "article_likes" of users and whether they like or dislike the article. With every like/dislike the datetime is saved and the id of the article. The like/dislike is saved as a bool in the "status" column.
id article_id user_id like_date status
1 8 2 2014-11-03 21:30:33 1
2 8 2 2014-11-03 21:31:00 0
3 8 3 2014-11-03 22:30:59 1
4 9 6 2014-11-03 22:36:25 1
5 9 2 2014-11-03 23:19:46 1
I like to get the amount of likes an article has. So only the status of the most recent date is valid for the count.
So the desired result would be:
article_id amount_likes
8 1
9 2
I want to get the result per article id, so not all at once.
Can anybody help me? Thanks!
This will solve your problem :)
SELECT article_id, SUM(IF(status = 1, 1, -1)) AS amount_likes FROM article_likes
GROUP BY article_id
If you store dislikes as -1 then:
SELECT article_id, SUM(status) AS amount_likes FROM article_likes
GROUP BY article_id
Try this:
SELECT `article_id`,COUNT(`user_id`) AS amount_likes FROM `links`
WHERE `status`='1' GROUP BY DATE(`like_date`), `user_id`;
Fiddle here - http://sqlfiddle.com/#!2/3b7bb6/4
Hope it helps
SELECT article_id, COUNT(IF(
SELECT CASE
WHEN status=1 THEN 'true'
ELSE 'false'
END),
'true','false'
)
)
FROM article_likes
GROUP BY article_id
ORDER BY article_id

Order by ID if two users have same number of credits

:-)
I have this script, which find a users position taken from the number of credits.
It all works, but i have a little problem. If two users have the same credits, both of them will be on the same position.
Can I do, so if there are more users with same credits, then the system need to order by the users ID and out from that give them a position?
This is my code so far:
$sql = "SELECT COUNT(*) + 1 AS `number`
FROM `users`
WHERE `penge` >
(SELECT `penge` FROM `users`
WHERE `facebook_id` = ".$facebook_uid.")";
$query_rang = $this->db->query($sql);
So if i have this:
ID -------- Credits
1 -------- 100
2 -------- 100
3 -------- 120
Then the rank list should be like this:
Number 1 is user with ID 3
Number 2 is user with ID 1
Number 3 is user with ID 2
ORDER BY credits DESC, id ASC. This will sort by credits and break ties with the id.
UPDATE
I understand now that you want the ranking information for the user, not just to sort the users by credits and ids. This will give you the complete list of users and their rankings:
SELECT #rank:=#rank+1 AS rank, users.id, users.facebook_id FROM users, (SELECT #rank:=0) dummy ORDER BY penge DESC, id ASC
Getting the row number is the tricky bit solved by this blog post:
http://jimmod.com/blog/2008/09/displaying-row-number-rownum-in-mysql/
$sql = "SELECT COUNT(*) + 1 AS `number` FROM `users` WHERE `penge` > (SELECT `penge` FROM `users` WHERE `facebook_id` = ".$facebook_uid.") ORDER BY COUNT(*) + 1 desc, users.ID";
$query_rang = $this->db->query($sql);
Later EDIT:
I don't understand why you still have the same results....
I made a quick test. I have created a table:
Test: ID (Integer) and No (Integer)
I have inserted some values:
id no
1 1
1 1
1 1
2 1
3 1
4 1
4 1
5 1
Now, if I run:
SELECT
id, COUNT(*) + 1 AS `number`
FROM
test
GROUP BY
id
I get:
id number
1 4
2 2
3 2
4 3
5 2
But if I add ORDER BY:
SELECT
id, COUNT(*) + 1 AS `number`
FROM
test
GROUP BY
id
ORDER BY
count(*) desc, id
then I get:
id number
1 4
4 3
2 2
3 2
5 2

Categories