How can I get the biggest value? [duplicate] - mysql

This question already has answers here:
MIN/MAX vs ORDER BY and LIMIT
(6 answers)
Closed 5 years ago.
Here is my table:
-- log
+----+---------+------------+
| id | user_id | seen |
+----+---------+------------+
| 1 | 2342 | 1442664886 |
| 2 | 3244 | 1442665851 |
| 3 | 2342 | 1442711823 |
| 4 | 7654 | 1442864219 |
| 5 | 3244 | 1442954080 |
| 6 | 9984 | 1442984716 |
+----+---------+------------+
I want to get the biggest seen time for a specific user as last seen. I can do that by these two queries:
First query:
SELECT seen AS last_seen
FROM log
WHERE user_id = :id
ORDER BY seen DESC
LIMIT 1
Second query:
SELECT MAX(seen) AS last_seen
FROM log
WHERE user_id = :id
Well which one is the standard way? Should I go with which one? Is there any different in the performance?

They are both fine. Both will take advantage of an index on log(user_id, seen).
The first is often preferable because you can pull in the whole row and get information from other columns.

Related

Selecting for each row values from a related table [duplicate]

This question already has answers here:
MySQL pivot table query with dynamic columns
(3 answers)
Closed 9 months ago.
I am rather new to SQL, and I need some help. Suppose I have two tables, Person (with columns PID and Name) and Visit (with columns PID (fk) and Date), where each Person can have multiple Visits.
I would like to select every person (with a condition, omitted here) with all the visit dates on the same row as the person they belong to, like
| PID | Name | Date | Date | Date |
| ----| -------|--------- |----------|----------|
| 1 | Daniel | 25/01/21 | 13/06/21 | |
| 2 | Nicole | 26/01/21 | 18/06/21 | 07/10/21 |
| 3 | Kayla | 02/02/21 | 25/06/21 | |
I've tried
SELECT PersonID, Name (SELECT Date FROM Visit V WHERE V.PersonID = P.PersonID) FROM Person P
which obvisously doesn't work. MySQL says
#1242 - Subquery returned more than 1 row
which I by all means expected! How can I solve this?
This query will give you a bit different result (dates in one column), but it would be easy to parse if you need to:
SELECT person.PID,person.Name,group_concat(visit_date) as dates from person,visit where person.PID = visit.PID group by person.PID
It will be something like that:
+-----+-------+----------------------------------+
| PID | Name | Dates |
+-----+-------+----------------------------------+
| 1 | Marek | 2022-05-15,2022-05-16,2022-05-12 |
| 2 | Magda | 2022-05-16,2022-05-16,2022-05-16 |
+-----+-------+----------------------------------+```

MySQL bitwise comparison

I have mysql with a user table with answers from a poll saved as a bitwise. How do I find the user with most or least common answers with the reference bitwise?
+------+---------+--+
| User | Answers | |
+------+---------+--+
| A | 1 | |
| B | 5 | |
| C | 10 | |
+------+---------+--+
Assuming by 'reference bitwise' you mean that you have another value that is a bitmask that you are trying to match against the Answers column, something like this should do it for you. In this case, I'm using '4' as the reference bitmask and myTable as the name of your table..
SELECT User, BIT_COUNT(Answers & 4) AS MatchedBits FROM myTable ORDER BY MatchedBits DESC
This returns:
+------+-------------+
| User | MatchedBits |
+------+-------------+
| B | 1 |
| A | 0 |
| C | 0 |
+------+-------------+
You can also add a LIMIT 1 clause to get just the top result, but of course that won't tell you if there is more than one top result with the same number of bits matched.

Select the max value from array in mysql query [duplicate]

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 3 years ago.
hi i have the following table (battles) :
+-----------+------------------------------------------+
| id | battles |
+-----------+------------------------------------------+
| 1 | 1;2 |
| 2 | 231;2 |
| 3 | 3330;0 |
| 4 | 11;333 |
| 5 | 32;3324 |
| 7 | 2;1 |
| 8 | 333:233 |
+-----------+------------------------------------------+
The table contains the win and loss of each player (win;lose)
how can i select the biggest win (3330;0)
Your last entry must be
| 7 | 333;233
to work properly. i believe it is only a typo
SELECT id,battles, maximal
From battles t inner join
(Select
MAX(SUBSTRING_INDEX(battles,';',1)+0) maximal
FRom battles) t1 on t1.maximal = SUBSTRING_INDEX(t.battles,';',1);
The result is
d battles maximal
3 3330;0 3330
If you had more ids with 3300 then they would also appear in the result

Calculating row indices with subquery having joins, results in A*B examined rows

This question is derived from a one I started previously: Incorrect row index when grouping
Due to different natures, I'm asking here and will provide the answer back there once I have resolved this issue.
I thought about subqueries, and came up with this:
SELECT
mq.*,
#indexer := #indexer + 1 AS indexer
FROM
(
SELECT
p.id,
p.tag_id,
p.title,
p.created_at
FROM
`posts` AS p
LEFT JOIN
`votes` AS v
ON p.id = v.votable_id
AND v.votable_type = "Post"
AND v.deleted_at IS NULL
WHERE
p.deleted_at IS NULL
GROUP BY
p.id
) AS mq
JOIN
(SELECT #indexer := 0) AS i
Which actually works, I get the desired result:
+----+--------+------------------------------------+---------------------+---------+
| id | tag_id | title | created_at | indexer |
+----+--------+------------------------------------+---------------------+---------+
| 2 | 2 | PostPostPost | 2014-10-23 23:53:15 | 1 |
| 3 | 3 | Title | 2014-10-23 23:56:13 | 2 |
| 4 | 2 | GIFGIFIGIIF | 2014-10-23 23:59:03 | 3 |
| 5 | 2 | GIFGIFIGIIF | 2014-10-23 23:59:03 | 4 |
| 6 | 4 | My new avatar | 2014-10-26 22:22:30 | 5 |
| 7 | 5 | Hi, haiii, oh Hey ! | 2014-10-26 22:38:10 | 6 |
| 8 | 6 | Mclaren testing stealth technology | 2014-10-26 22:44:15 | 7 |
| 9 | 7 | Just random thoughts while pooping | 2014-10-26 22:50:03 | 8 |
+----+--------+------------------------------------+---------------------+---------+
The problem now is... I ran a EXPLAIN query, to see how fast it works. And, I have a number there that is really bugging me:
Well, the number is obvious: 252 * 1663 = 419076.
This worries me, though - is the row count normal there, or I have to optimize the query? And if so, then how do I optimize this one?
As of MySQL version 5.7 all joins are treated as nested loop joins.
MySQL resolves all joins using a nested-loop join method. This means that MySQL reads a row from the first table, and then finds a matching row in the second table, the third table, and so on.
So to answer your question... no, you won't be able to get that row count down. However, by adding indexes to your join columns you may be able to achieve faster results but your row count will be the same.

Creating Temporary Column Order By Slow

So basically what I'm trying to do is get gained experience, ordering it, then only displaying top 5 or 50. Now note that I'm not SQL expert but I have knowledge of indexes as well as file sorting. The query that I have is filesorting most likely due to "gained_xp" not being a index-- let alone even a column as it's only temporary. There's no clear explanation how to fix this as I'm trying to contain it all in one query. I'm trying to sort nearly 13k rows with that number only expanding. I'd also need the number of rows to be dynamic as well as the time since. Any help would be appreciated. Thank you
Explain Output: Using where; Using temporary; Using filesort
Indexes include: time userid override overallXp overallLevel overallRank
The closest I've gotten to order all rows (which never ends up completing and ends in a mysql reboot) are:
SELECT FROM_UNIXTIME(time, '%Y-%m-%d'), t_u.userid as uid, MAX(t_u.OverallXP)-(SELECT overallXP FROM track_updates WHERE `userid` = t_u.userid AND `time`>'1394323200' ORDER BY id ASC LIMIT 1) as gained_xp
FROM track_updates t_u
WHERE t_u.time>'1394323200'
GROUP BY t_u.userid
If I'd run a query that selects only one user and works correctly is:
SELECT FROM_UNIXTIME(time, '%Y-%m-%d'), (t_u.overallXP)-(SELECT overallXP FROM track_updates WHERE `userid`='1' ORDER BY `id` ASC LIMIT 1) as gained_xp, t_u.userid
FROM track_updates t_u
WHERE t_u.userid='1' AND t_u.time>'1393632000'
ORDER BY t_u.time DESC
LIMIT 1
Sample Data per request:
____________________________________________________________________
| id | userid | time | overallLevel | overallXP | overallRank |
| 1 | 1 | 1394388114 | 1 | 1 | 1 |
| 2 | 1 | 1394389114 | 2 | 10 | 1 |
| 3 | 2 | 1394388114 | 1 | 1 | 2 |
| 4 | 2 | 1394389114 | 1 | 5 | 2 |
| 5 | 2 | 1394390114 | 2 | 7 | 2 |
Output (most recent time; gained xp current-initial; ordered by gain_xp):
____________________________________________
| id | time | userid | gained_xp |
| 1 | March 9th 2014 | 1 | 9 |
| 2 | March 9th 2014 | 2 | 6 |