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.
Related
I have a table in which all action logs are stored. It contains "user_id" (to mark user), "statement_id" (to mark statement that has been worked on), "action_date" (to mark action time) and "action_type" (to mark what action was done). A user can work on many statements on which many actions can be performed.
I need to produce a query that will show what statements were worked on at a specific time (let's say from March 1, 2018 to March 30, 2018) - that I can do. The difficulty for me is to limit the outcome. I mean precisely how to limit the outcome from this:
Statements that were worked on: 30, 30, 30, 18, 18, 42, 42, 42
To this:
Statements that were worked on: 30, 18, 42
I tried to work with queries like this one but I'm no professional. I find it difficult to understand the concept of some limiting SQL commands.
SELECT * FROM action_log
WHERE user_id = 1
AND action_date >= 1519858800
AND action_date <= 1522447200
GROUP BY user_id
HAVING user_id = 1
ORDER BY id DESC
I would be very grateful for any help.
I think you are looking for SELECT DISTINCT:
SELECT DISTINCT statement_id
FROM action_log al
WHERE user_id = 1 AND
action_date >= 1519858800 AND action_date <= 1522447200
ORDER BY statement_id DESC;
You might find this easier to maintain by using UNIX_TIMESTAMP():
SELECT DISTINCT statement_id
FROM action_log al
WHERE user_id = 1 AND
action_date >= UNIX_TIMESTAMP('2018-03-01') AND
action_date <= UNIX_TIMESTAMP('2018-03-30')
ORDER BY statement_id DESC;
I guess you only need unique values.
In SQL there is a special statement for this.
Use SELECT DISTINCT
SELECT DISTINCT * FROM action_log WHERE user_id = 1 AND action_date >= 1519858800 AND action_date <= 1522447200 GROUP BY user_id HAVING user_id = 1 ORDER BY id DESC;
You can use between for comparing action_date. And you can eliminate having condition because that is already used in where. WHERE user_id = 1 and HAVING user_id = 1 will result you the same. Hope following code will work for you.
SELECT * FROM action_log WHERE user_id = 1 AND action_date between '1519858800' AND '1522447200' GROUP BY statement_id ORDER BY id DESC
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 have a MySql table that consists of 2 basic things:
The id and a value.
To show that on my page, i need to select, for example, the last 100 rows on reversed order.
So imagine that someone is putting data on it:
Id, value
1, 10
2, 9
3, 21
4, 15
i need, to select the last "3" rows (LIMIT + ORDER Clause), but not like this: 4,3,2 but like this: 2,3,4.
I know how to do that on code, but maybe there is a simple solution for that on Mysql and i don`t know.
Thanks
My SQL Query is like this right now:
SELECT `Data`.`id`, `Data`.`log_id`, `Data`.`value`, `Data`.`created` FROM `control_panel`.`datas` AS `Data` WHERE `Data`.`id` > 1000 AND `Data`.`log_id` = (2) ORDER BY `Data`.`id` DESC LIMIT 100
You need to wrap the first ORDER BY in a subselect which will return a limited selection ordered in descending order, then you can order that result in the outer query in ascending order:
SELECT
a.*
FROM
(
SELECT id, value
FROM tbl
ORDER BY id DESC
LIMIT 3
) a
ORDER BY
a.id
One way to do this would be with a sub-select.
SELECT *
FROM (SELECT * FROM table_name ORDER BY id DESC LIMIT 3) tmp
ORDER BY id ASC
simply
SELECT t.*
(SELECT * FROM table_name
ORDER BY column_name DESC
LIMIT 0,3) t
ORDER BY t.column_name ASC
use DESC to descending order, ASC to increasing order
Is there a possible way to do this:
I want to update a field 'rank' according to the ORDER BY place.
For example: (pseudocode)
If id order by place = 1 then update rank field to place were id=get id
rank place id
1 1 5 PC
2 2 8 MAC
is this possible?
Something like this?
UPDATE tbl_name
SET rank = 1
WHERE id = (
SELECT id
WHERE condition
ORDER BY place DESC
LIMIT 1
)
Or from your comment (I think MySQL http://dev.mysql.com/doc/refman/5.0/en/update.html):
UPDATE tbl_name
SET rank = 10
WHERE id = 9
ORDER BY wins DESC
LIMIT 1
You can always do a SELECT to check if these are the records you wish to UPDATE as well:
SELECT *
FROM tbl_name
WHERE id = (
SELECT id
WHERE condition
ORDER BY place DESC
LIMIT 1
)
OR
SELECT *
FROM tbl_name
WHERE id = 9
ORDER BY wins DESC
LIMIT 1
Some RDBMS have a ROWNUM pseudocolumn in queries you can use for this.
You did not specify what database you are using, for example Oracle has this.
I am coding a blog post kind of thing, where the author will post the article and it will be displayed in the front end, my problem starts for selecting the posts as i have to meet certain conditions for posting the news in the front end,
I have 4 fields in the database namely
title
pic_title
pic_brief
pic_detail
you guessed it right apart from the title table the rest of three will hold the path to the images in varchar datatype, which will be used to display as the post, the format of the front end is such that
a) there will be total of eight post
displaying in the front end (eight
entries from the database)
b) there will be three post on the top which will include the value from
the table title, pic_title and
pic_brief (total of 3 values)
c) and the rest five will contain just the title and pic_title
(excluding the three entries of top)
Please NOTE: i want the second query to exclude the top 3 record
which already exist in the top i.e
(first query = 3 post in descending
order, second query = 8 - first 3 = 5
post)
The Order of the Post i want is by id DESC
EDIT: I took the first query as
SELECT * FROM news ORDER BY id DESC LIMIT 3
Now if i take the same second query and try populating the values by desc order again the same records will be accessed
In simple words i want a query that will skip the last three records order by id DESC
How do i achieve this feat in PHP?
If you just want the SQL, here it is:
First query
SELECT * FROM `table` LIMIT 3
Second query
SELECT * FROM `table` LIMIT 3,5
(where table is the name of your table of course. Of course you may want to add some ORDER BY clause. To execute these queries in PHP, I suggest reading the manual. If you have any specific problems after doing so, then you can post a new question.
This is a situation where I'd likely opt to select all eight records at once - the less trips to the database, the better.
SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8
...because the rest is just presentation:
$query = sprintf("SELECT t.title,
t.pic_title,
t.pic_brief
FROM TABLE t
ORDER BY t.id DESC
LIMIT 8");
// Perform Query
$result = mysql_query($query) or die( mysql_error() );
$rowcount = 1;
// Use result
while ($row = mysql_fetch_assoc($result)) {
if(rowcount <= 3) {
echo $row['title']
echo $row['pic_title']
echo $row['pic_brief']
} else {
echo $row['title']
echo $row['pic_title']
}
++$rowcount;
}
first query will be like this
"select title, pic_title , pic_brief from table_name order by post_id desc limit 0 , 3"
and rest of five will be
"select title, pic_title from table_name order by post_id desc limit 3 , 5"
second query will exclude the three results returned by first query...
If you want more perfection you can collect all three Ids returned by first query and can add NOT IN in second query.
"select title, pic_title from table_name where post_id not in (1,2,3) order by post_id desc limit 0 , 5";