I have page where people can post comments and page where people can click "follow" on other people profiles (same as LIKE on Facebook)
I would like to have SELECT query that will post all the comments I have, but will order them with the follow way:
first, print the 2 newest comments (they must been posted this week) of the lastest people you click FOLLOW.
second, post the rest of the posted, order them by create-date
(I'm using linux time)
Can you help me with the SQL query?
this is my current SELECT query. it pull all comment by create-date:
SELECT id, userID, text, createDate FROM `comments` AS comment WHERE (comment.refID = 0) AND (comment.pageName = 'yard') AND 1=1 ORDER BY comment.createDate DESC LIMIT 0, 20
"followers" table looks like this:
userID ownerID createDate
1 2 1439019657
1 4 1438940399
"comments" table looks loke this:
id userID pageName refID text createDate
220 1 yard 0 text1 1438030967
227 1 yard 0 text2 1438031704
228 1 yard 0 text3 1438031704
I might've messed up followers' relations. Example data looks incoplete for full context. It shows userID=1 comments for sure, but either no one who follows userID=1 or both 3 and 4 follow him. No idea what refID is doing in comments table. Query shows only a concept anyway - you'll figure out details.
SELECT un.* FROM ((
SELECT 1 as priority, comment.id, comment.userID, comment.text, comment.createDate
FROM `comments` as comment
INNER JOIN `followers` as follower ON follower.userID = comment.userID
WHERE comment.refID = 0
AND comment.pageName = 'yard'
AND ...
ORDER BY follower.createDate DESC LIMIT 2
) UNION DISTINCT (
SELECT 2 as priority, id, userID, text, createDate
FROM `comments` as comment
WHERE comment.refID = 0
AND comment.pageName = 'yard'
)) as un ORDER BY un.priority, un.createDate DESC LIMIT 20
Related
I have page where people can post comments and page where people can click "follow" on other people profiles (same as LIKE on Facebook)
I would like to have SELECT query that will post all the comments I have, but will order them with the follow way:
First, print the 2 newest comments (they must been posted this week) of the lastest people you click FOLLOW.
Second, post the rest of the posted, order them by create-date
(I'm using linux time)
Can you help me with the SQL query?
This is my current SELECT query. it pull all comment by create-date:
SELECT
id, userID, text, createDate
FROM `comments` AS comment
WHERE (comment.refID = 0)
AND (comment.pageName = 'yard')
AND 1=1
ORDER BY comment.createDate DESC LIMIT 0, 20
"followers" table looks like this:
userID ownerID createDate
1 2 1439019657
1 4 1438940399
(user 1 is following after user 2 and 4)
"comments" table looks loke this:
id userID pageName refID text createDate
220 1 yard 0 text1 1438030967
227 1 yard 0 text2 1438031704
228 1 yard 0 text3 1438031704
(userID - which user publish the comment. refID - always "0". pageName - always "yard")
So is this case, if I'm user number 1, than I would like to see the newest 2 comments of users 2 and 4 (only if they where made in the last week) and than to see all the rest of the comments (of all users) order by date (without , of course, the once that I already saw)
You are going to have to split this up into 2 queries.. ..and I am guessing at some of the table relationships here..
// get the last 2 comments from followed users..
SELECT *
FROM comments
WHERE userID IN (
SELECT ownerID
FROM followers
WHERE userID = ?
) ORDER BY createDate DESC
LIMIT 2
// then get the rest, removing already returned comments
SELECT *
FROM comments
WHERE id NOT IN (
-- either put the above query in here
-- or buuild an array of the 'id's when outputting the results above
-- and use that in here to prevent them being returned again
) ORDER BY createDate DESC
(select com.userID,com.page,com.text
from followers as fol
JOIN comments as com
ON fol.ownerId=com.userId
where
(
from_unixtime(com.createDate) BETWEEN
(
UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -14 DAY) AND UNIX_TIMESTAMP(NOW())
)
Order BY com.createDate desc
)
Union
(select com.userID,com.page,com.text
from comments as com
where com.id NOT In
(select com.id
from followers as fol
JOIN comments as com
ON fol.userId=com.userId
where
(
from_unixtime(com.createDate) BETWEEN
(
UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -14 DAY) AND UNIX_TIMESTAMP(NOW())
)
)
Order BY com.createDate desc
)
Explanation:
There are two queries merged in one using union.
Select statement will give all the data follower comments.
this is accomplished using Join.
Select statement to get all the other comments then the comments of the above 1st query.
the only thing that is not clear is how you are deciding whether the
comments is been read by the user (Insufficient information)
I'm looking to see if the last 3 rows have the same userId...
I've tried count, select distinct with no luck. Any ideas?
id userId gameId switchId won
--------------------------------
1 1515 5 475 0
2 1515 5 475 0
3 1515 5 475 0
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$st = $db->prepare("SELECT COUNT(userId) AS total FROM arcadeGamesInPlay WHERE userId=:userid,gameId=:gameId AND switchId=:switchId AND won=:won ORDER by id DESC LIMIT :limit"); // need to filter for next auction
$st->bindParam(':userId', $userId);
$st->bindParam(':gameId', $gameId);
$st->bindParam(':switchId', $switchId);
$st->bindParam(':won', $won);
$st->bindParam(':limit', $limit);
$limit=3;
$won=0;
$st->execute();
$r = $st->fetch(PDO::FETCH_ASSOC);
$playedLastThreeGames= $r['total'];
You need a nested query for this. Imagine a query like this:
SELECT COUNT(DISTINCT userId) FROM arcadeGamesInPlay WHERE id IN (1, 2, 3);
This will return the number of unique userids that were found in the three rows listed - if it returns 1, then you know they're all the same.
You can combine that with a query to select the last three rows. Perhaps something like this:
SELECT id FROM arcadeGamesInPlay ORDER BY id DESC LIMIT 3
...although you may want to add a WHERE clause as well.
Altogether, your query would look like this:
SELECT COUNT(DISTINCT userId)
FROM arcadeGamesInPlay
WHERE id IN (
SELECT id
FROM arcadeGamesInPlay
ORDER BY id DESC
LIMIT 3
);
All that being said, you haven't specified what database you're actually connecting to - and if it's MySQL, you're going to run into problems, because MySQL doesn't support a LIMIT clause on a subquery with the IN operator.
An alternative form of the subquery that will work with MySQL looks like this:
SELECT COUNT(DISTINCT userId)
FROM (
SELECT userId
FROM arcadeGamesInPlay
ORDER BY id DESC
LIMIT 3
) u;
An SQL Fiddle that shows both queries can be seen here: http://sqlfiddle.com/#!2/dda29/4
I've commented out the LIMIT part of the first query so it will work in MySQL. If you change the database engine to something else (PostgreSQL for example), you should be able to uncomment that and have both queries work properly.
I want to make a fast table structure for news site with php and mysql. My database structure is ID, title, content, cat_ids (; separedet IDs of categories - ;5;10;15;20;), active, publish_date.
I want to make a fast query to select news from this table. Something like that:
SELECT id
FROM news
WHERE cat_ids LIKE '%;15;%'
AND active = 1
AND publish_date < NOW()
ORDER by publish_date DESC
LIMIT 0, 10
But if my table is 2-3GB the query is very slow. I need some ideas to make structure and make the select faster.
Instead of using cat_ids column, try creating a news_cats table with news_id and cat_id, and using this query:
SELECT id
FROM news JOIN news_cats ON news_id = id
WHERE cat_id = 15
AND active = 1
AND publish_date < NOW()
ORDER by publish_date DESC
LIMIT 0, 10
Some suggestions as below:
1) Create index on "active" field
2) Create index on "publish_date" field
3) Create separate table for category and news relation and remove "cat_ids" field from news table
New table might look like below:
news_category_ids
news_id
category_id
It can have multiple rows for each news_id, if news item falls in 3 categories, it will have 3 rows
Then use SQL like below:
SELECT news.id
FROM news INNER JOIN news_category_ids ON news.id = news_category_ids.news_id
WHERE 1
AND news.active = 1
AND news_category_ids.cat_id = 15
AND news.publish_date < NOW()
ORDER by news.publish_date DESC
LIMIT 0, 10
Okay so I have a table that has the following
KEY username password score
The above columns are not in any specific order.
I want to send my Database a username and have it send me back what rank that user name is based on its score. So for example if I had 10 people in there and the 3rd person in has the highest score. When I pass the 3rd persons username in I want it to send back 1.
Is this possible?
I have been trying things like this
$result = mysql_query("SELECT * FROM tablename where username='$username' ORDER BY score DESC");
but it doesnt seem to give me the row number
This will handle ranks that have the same score.
SELECT d.*, c.ranks
FROM
(
SELECT Score, #rank:=#rank+1 Ranks
FROM
(
SELECT DISTINCT Score
FROM tableName a
ORDER BY score DESC
) t, (SELECT #rank:= 0) r
) c
INNER JOIN tableName d
ON c.score = d.score
// WHERE d.username = 'Helen'
SQLFiddle Demo (Ranking with duplicates)
SQLFiddle Demo (with filtering)
for example
KEY username password score Ranks
1 Anna 123 5 3
2 Bobby 345 6 2
3 Helen 678 6 2
4 Jon 567 2 4
5 Arthur ddd 8 1
for better performance, add an INDEX on column Score,
ALTER TABLE tableName ADD INDEX (Score)
SELECT
(SELECT COUNT(*)+1 FROM tablename WHERE score > t.score) as rank,
*
FROM
tablename t
where
username='$username'
The ORDER BY in your query is useless since you're only returning one row.
I have a user table with id, username and food_id columns. The idea is the user stored their favorite food and we come up with a league table of foods and I want to generate a report of the top votes for the each food type. I am using MySQL and PHP.
For clarity, here is an example of the table:
id food_id username
1 1 Bob
2 100 Jane
3 200 Andy
4 1 Maggy
5 100 Rich
6 100 Mick
7 1 Kevin
How do I write the query to list the foods that have the most votes. I want to limit the result to x number, say top 100. In this case I want the result to be as follows:
food_id score
1 3
100 4
I hope the question is clear enough. The query is beyond me but I am sure it must be possible to do it using DISTINCT and COUNT in some way or other. Perhaps it's sub queries?
select food_id, count(*) score
from myTable
group by food_id
order by score desc limit 100
SELECT F.food_name,
COUNT(*) AS score
FROM myTable AS M
INNER JOIN food_table AS F
ON F.food_id = M.food_id
GROUP BY F.food_name
ORDER BY score DESC limit 100
select count(*) as top100 from table group by food_id order by top100 desc limit 100
SELECT f.`food_id`, COUNT(*) AS `count`
FROM `fav_food_table` f
GROUP BY f.`food_id`
ORDER BY `count` DESC
LIMIT 100;