I have table like this
id | serial_num | version | .....
1 | 1 | 1 | .....
2 | 2 | 1 | .....
3 | 2 | 2 | .....
4 | 3 | 1 | .....
5 | 4 | 1 | .....
6 | 5 | 1 | .....
7 | 5 | 2 | .....
8 | 5 | 3 | .....
Now what I want to select is to get rows with max version and unique serialn_num ...
The result would be:
id | serial_num | version | .....
1 | 1 | 1 | .....
3 | 2 | 2 | .....
4 | 3 | 1 | .....
5 | 4 | 1 | .....
8 | 5 | 3 | .....
My SQL is a bit more complicated and that is why I don't solve the problem by using MAX()... I have few left joins etc ...
any ideas?
Best regards and thank you for your time!
Try this:
SELECT yourtable.*
FROM yourtable
WHERE (serial_num, version) in (select serial_num, max(version)
from yourtable
group by serial_num)
Subquery will return the maximum version for serial_num, so this will return all rows where serial_num has the maximum value. See this fiddle.
You can use a subquery to find the max values and then join back to your table:
select t1.id,
t1.serial_num,
t1.version
from yourtable t1
inner join
(
select serial_num,
max(version) version
from yourtable
group by serial_num
) t2
on t1.serial_num = t2.serial_num
and t1.version = t2.version
See SQL Fiddle with Demo
Result:
| ID | SERIAL_NUM | VERSION |
-----------------------------
| 1 | 1 | 1 |
| 3 | 2 | 2 |
| 4 | 3 | 1 |
| 5 | 4 | 1 |
| 8 | 5 | 3 |
Selecting id for a group by query is useless. You should only select the column you are using in group by and other columns that are being applied aggregate functions.
Hope this works for you.
SELECT id,
serial_num,
Max(`version`) `version`
FROM tbl1
GROUP BY serial_num
Related
Given the following data set, I want to select the rows (all columns) comprised between the first one and the last of the result of selecting 'n' distinct on col1 and col2.
pkey | col1 | col2 | day | Other columns...
1 | a | 1 | 1 |
2 | b | 2 | 1 |
3 | b | 2 | 1 |
4 | c | 3 | 1 |
5 | c | 4 | 1 |
6 | a | 5 | 2 |
7 | a | 5 | 2 |
8 | b | 6 | 2 |
9 | c | 7 | 2 |
10 | c | 8 | 2 |
For n = 5, the result must be:
pkey | col1 | col2 | day | Other columns...
1 | a | 1 | 1 |
2 | b | 2 | 1 |
3 | b | 2 | 1 |
4 | c | 3 | 1 |
5 | c | 4 | 1 |
6 | a | 5 | 2 |
7 | a | 5 | 2 |
I am trying by using SELECT DISTINCT col1, col2 FROM sampletable as a base but then I have no access to the other columns. How could this be achieved?
Edit:
Changed description to be more clear regarding what I want
Changed col2 of rows 6 and 7 from 1 to 5 to be closer to my real data.
SELECT a.*
FROM sampletable AS a
INNER JOIN (SELECT DISTINCT col1, col2 FROM sampletable LIMIT 5) AS b
ON a.col1 = b.col1 AND a.col2 = b.col2
Select a.* from sampletable a inner join (
SELECT MIN(pkey) as pkey FROM sampletable GROUP BY col1,col2 limit 5) b on a.pkey = b.pkey
Use this query.
Another different way:
SELECT DISTINCT(CONCAT(col1, col2)) AS fgroup, pkey, day... FROM [table] GROUP BY fgroup LIMIT [LIMIT]
Replace [table] by your table name.
Replace [limit] by the desired limit.
Replace the "..." by all the extra fields that you want to list.
Let's say I have a table like this:
project_id | created_by | created
1 | 3 | 2015-04-01
2 | 3 | 2015-04-07
3 | 4 | 2015-05-01
4 | 4 | 2015-05-02
and I want to select these columns, then a count of how many projects were created by the created_by before each project, to look like this:
project_id | created_by | created | previous by created_by user
1 | 3 | 2015-04-01 | 0
2 | 3 | 2015-04-07 | 1
3 | 4 | 2015-05-01 | 0
4 | 4 | 2015-05-02 | 1
How do I select the count for that last column? I've tried count(case where [condition] then 1 else null end) but I keep only getting one row of results when I use that.
You can use a subquery which i already mentioned in the comments.
For Example the query could look like this:
SELECT t1.*,
(SELECT count(*)
FROM Table t2
WHERE UNIX_TIMESTAMP(t2.date) < UNIX_TIMESTAMP( t1.date)
AND t2.created_by = t1.created_by) before
FROM Table t1
It will return the columns of the the Table 'Table' and the result of the subquery as column 'before' which contains the count of before created rows.
Is this what you are after ?
select
project_id,
created_by,
created,
rn as `previous by created_by user`
from(
select
project_id,
created_by,
created,
#rn:=if(#prev_created_by = created_by,#rn+1,0) as rn,
#prev_created_by := created_by
from project,(select #rn:=0,#prev_created_by:=null)x
order by created_by,created
)x;
Here is a test case
mysql> select * from project ;
+------------+------------+------------+
| project_id | created_by | created |
+------------+------------+------------+
| 1 | 3 | 2015-04-01 |
| 2 | 3 | 2015-04-07 |
| 3 | 4 | 2015-05-01 |
| 4 | 4 | 2015-05-02 |
+------------+------------+------------+
4 rows in set (0.00 sec)
The above query will have
+------------+------------+------------+-----------------------------+
| project_id | created_by | created | previous by created_by user |
+------------+------------+------------+-----------------------------+
| 1 | 3 | 2015-04-01 | 0 |
| 2 | 3 | 2015-04-07 | 1 |
| 3 | 4 | 2015-05-01 | 0 |
| 4 | 4 | 2015-05-02 | 1 |
+------------+------------+------------+-----------------------------+
Select t1.project_id , t1.created_by, t1.created,count(t2.created)
from t1 , (select created_by,created from t1) as t2
Where t1.created_by=t2.created_by and t1.created>t2.created
group by t1.project_id ,t1.created_by, t1.created
Suppose I have such a table:
+-----+---------+-------+
| ID | TIME | DAY |
+-----+---------+-------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 1 | 1 | 2 |
| 2 | 2 | 2 |
| 3 | 3 | 2 |
| 1 | 1 | 3 |
| 2 | 2 | 3 |
| 3 | 3 | 3 |
| 1 | 1 | 4 |
| 2 | 2 | 4 |
| 3 | 3 | 4 |
| 1 | 1 | 5 |
| 2 | 2 | 5 |
| 3 | 3 | 5 |
+-----+---------+-------+
I want to fetch a table which represents 2 IDs which got the largest sum of TIME within the last 3 days (means from 3 to 5 in a DAY column)
So the correct result would be:
+-----+---------+
| ID | SUM |
+-----+---------+
| 3 | 9 |
| 2 | 6 |
+-----+---------+
The original table is much larger and more complex. So i need a generic approach.
Thanks in advance.
And so I just learned that MySQL used LIMIT instead of TOP...
fiddle
CREATE TABLE tbl (ID INT,tm INT,dy INT);
INSERT INTO tbl (id, tm, dy) VALUES
(1,1,1)
,(2,2,1)
,(3,3,1)
,(1,1,2)
,(1,1,1)
SELECT ID
,SUM(SumTimeForDay) SumTimeFromLastThreeDays
FROM (SELECT ID
,SUM(tm) SumTimeForDay
FROM tbl
GROUP BY ID, dy
HAVING dy > MAX(dy) -3) a
GROUP BY id
ORDER BY SUM(SumTimeForDay) DESC
LIMIT 2
select t1.`id`, sum(t1.`time`) as `sum`
from `table` t1
inner join ( select distinct `day` from `table` order by `day` desc limit 3 ) t2
on t2.`da`y = t1.`day`
group by t1.`id`
order by sum(t1.`time`) desc
limit 2
I am working on the project and one of the things that I need to do, is to select some data
table:
id | unit_id | data1 | data2 | data 3 | data4 | TimeStamp
1 | 1 | 1 | 1 | 1 | 2012-10-18 18:17:42
2 | 1 | 2 | 2 | 2 | 2012-10-18 18:18:42
3 | 1 | 3 | 5 | 3 | 2012-10-20 18:19:42
4 | 1 | 4 | 7 | 4 | 2012-10-21 18:20:42
5 | 1 | 5 | 8 | 8 | 2012-10-22 18:21:42
6 | 2 | 1 | 1 | 1 | 2012-10-18 18:17:42
7 | 2 | 2 | 2 | 4 | 2012-10-19 18:18:42
8 | 2 | 3 | 2 | 5 | 2012-10-20 18:19:42
9 | 2 | 4 | 3 | 6 | 2012-10-21 18:20:42
and what I need, is to get Single LATEST value for EACH unit_id
The following query will group the records by unit_id and identifies the one with latest timestamp, joins those results with the same table and selects the record with the unit_id and timestamp values.
SELECT
a.*
FROM
MyTable a
JOIN (SELECT
unit_id,
MAX(TimeStamp) 'TimeStamp'
FROM
MyTable
GROUP BY unit_id
) as b
ON a.unit_id = b.unit_id AND a.Timestamp = b.TimeStamp
By using GROUP BY clause, like
SELECT
unit_id, max(TimeStamp)
FROM
table3
GROUP BY
unit_id
Try this
SELECT unit_id , max(tstamp)
FROM t
GROUP BY unit_id
SELECT max(timestamp),unit_id FROM table GROUP BY unit_id
I have a problem, please see my database:
-------------------
| id | article_id |
-------------------
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 3 |
| 8 | 3 |
| 9 | 3 |
| 10 | 3 |
And I want to receive something like this (order by votes, from max to min):
---------------------------
| id | article_id | votes |
---------------------------
| 1 | 3 | 5 |
| 2 | 1 | 3 |
| 3 | 2 | 2 |
Could you please help me to write proper sql query?
SET #currentRow = 0;
SELECT #currentRow := #currentRow + 1 AS id, t.article_id, t.c AS `votes`
FROM (
SELECT article_id, count(*) as `c`
FROM table_votes
GROUP BY article_id
) t
ORDER BY t.c DESC
please note that you can't select an id column like this in this context, and your "expected result" is incorrect. I tried to adapt it at a maximum.
cheers
SELECT article_id, COUNT(article_id) AS votes
FROM votes_table
GROUP BY article_id
ORDER BY votes DESC;