I have the following SQL SERVER table:
+--------+-------+-------+------+
| Person | Phone | Count | Rank |
+--------+-------+-------+------+
| A | X | 1 | 1 |
| B | X | 9 | 2 |
| C | X | 5 | 3 |
| T | Y | 6 | 1 |
| S | Y | 2 | 2 |
+--------+-------+-------+------+
I need the result to be the Person and Phone value where the Rank is equal to 1, but the MAX count value for the specific Phone for example:
+--------+-------+----------+------+
| Person | Phone | MaxCount | Rank |
+--------+-------+----------+------+
| A | X | 9 | 1 |
| T | Y | 6 | 1 |
+--------+-------+----------+------+
I can join on the table twice but was wondering if I can use MAX to achieve this?
You can use a subquery:
SELECT T.Person, T.Phone, (SELECT MAX(Count)
FROM YourTable AS TI
WHERE TI.Phone = T.Phone) AS MaxCount, T.[Rank]
FROM YourTable AS T
WHERE T.[RANK] = 1
SQL Fiddle
You can use MAX(Count)OVER(PARTITION BY Phone), for example with a CTE:
WITH CTE AS
(
SELECT Person,
Phone,
MaxCount = MAX(Count)OVER(PARTITION BY Phone),
Rank
FROM dbo.TableName
)
SELECT Person,
Phone,
MaxCount,
Rank
FROM CTE
WHERE Rank = 1
An alternative solution is to use outer apply like this:
SELECT Person,
Phone,
MaxCount,
[Rank]
FROM YourTable t1
OUTER APPLY (SELECT MAX([count]) AS MaxCount FROM YourTable WHERE Phone = t1.Phone) oa
WHERE [Rank] = 1
Related
+--------+--------+--------+------------+
| line | field1 | count|
| x | a | 2 |
| x | b | 2 |
| x | c | 1 |
| y | a | 1 |
| y | b | 1 |
| y | c | 1 |
| y | d| 1 |
As you can see above table represented line is grouped field, I try to get query result something like that or similiar:
+--------+--------+--------+------------+
| line | field1-percentage|
| x | a-%40,b-%40,c-%20 |
| y | a-%25,b-%25,c-%20 |
Column names altered (count is Reserved word).
For MySQL 8+ use
WITH cte AS ( SELECT category, entity, SUM(amount) amount
FROM test
GROUP BY category, entity WITH ROLLUP )
SELECT category, GROUP_CONCAT(t1.entity, '-%', ROUND(100 * t1.amount / t2.amount)) percentage
FROM cte t1
JOIN cte t2 USING (category)
WHERE t2.entity IS NULL
GROUP BY category;
For MySQL 5.x use:
SELECT category, GROUP_CONCAT(t1.entity, '-%', ROUND(100 * t1.amount / t2.amount)) percentage
FROM ( SELECT category, entity, SUM(amount) amount
FROM test
GROUP BY category, entity ) t1
JOIN ( SELECT category, SUM(amount) amount
FROM test
GROUP BY category ) t2 USING (category)
GROUP BY category;
fiddle
I have a table like so (I'm not sure how to format tables)
Category / Products / Purchases
1 | A | 12
1 | B | 13
1 | C | 11
2 | A | 1
2 | B | 2
2 | C | 3
Expected output:
1 | B | 13
2 | C | 3
However I keep on getting
1 | A | 13
2 | A | 3
ie. It just selects the first occurrence of the second column.
Here is my code:
SELECT Category, Products, MAX(Purchases) FROM myTable GROUP BY Category;
Use filtering in the where clause:
select t.*
from t
where t.purchases = (select max(t2.purchases) from t t2 where t2.category = t.category);
With NOT EXISTS:
select m.* from myTable m
where not exists (
select 1 from myTable
where category = m.category and purchases > m.purchases
)
See the demo.
Results:
| Category | Products | Purchases |
| -------- | -------- | --------- |
| 1 | B | 13 |
| 2 | C | 3 |
You can use row_number() to identify max purchase for each group or replace rownumber() to rank() if there are ties of max purchases for each group
Select Category, Products,
Purchases from (Select Category,
Products,
Purchases,
row_number() over (partition by
category, products order by
purchases desc) rn from table) t
where t.rn=1
)
I know that the title sounds horrible but I have no idea how to summarize it better. I'm pretty sure that somebody had the same problem before but I couldn't find anything. RDBMS: MySQL.
Problem:
I have the following (simplified) table:
+------+------------+---------------------------------+
| name | date | score |
+------+------------+---------------------------------+
| A | 01.01.2015 | 1 |
| A | 01.02.2015 | 3 |
| A | 01.03.2015 | 4 |
| B | 01.01.2015 | 3 |
| B | 01.02.2015 | 4 |
| B | 01.03.2015 | 5 |
| C | 01.01.2015 | 1 |
| C | 01.02.2015 | 2 |
| C | 01.03.2015 | 3 |
+------+------------+---------------------------------+
There is no unique constraint or PK defined.
The table represents a highscore of a game. Every day the score of all players are inserted with values that are: name, points, now(),...
The data represent a snapshot of the score of each player at a specific time.
I want the most recent entry for each user only but only for the highest X players. So the result should look like
+------+------------+---------------------------------+
| name | date | score |
+------+------------+---------------------------------+
| A | 01.03.2015 | 4 |
| B | 01.03.2015 | 5 |
+------+------------+---------------------------------+
C doesn't appear since he's not in the top 2 (by score)
A appears with the most recent row (by date)
B appears, like A, with the most recent row (by date) and because he is in the top 2
I hope it becomes clear what I mean.
Thanks in advance!
I understand that what you need is to first select the X players who've gotten the highest score and then get their latest performance. In this case, you should do this:
SELECT *
FROM tablename t
JOIN
(
SELECT t.name, max(t.date) as max_date
FROM tablename t
JOIN
(
SELECT name
FROM
(
SELECT name, max(score) as max_score
FROM table_name
GROUP BY name
) all_highscores
ORDER BY max_score DESC
LIMIT X
) top_scores
ON top_scores.name = t.name
GROUP BY t.name
) top_last
on t.name = top_last.name
and t.date = top_last.date;
I have a table structure as given below and what I'd like to be able to do is retrieve the top three records with the highest value for each Company code.
I've googled and I couldn't find a better way so hopefully you guys can help me out.
By the way, I'm attempting this in MySQL and SAP HANA. But I am hoping that I can grab the "structure" if the query for HANA if I can get help for only MySQL
Thanks much!
Here's the table:
http://pastebin.com/xgzCgpKL
In MySQL you can do
To get exactly three records per group (company) no matter ties emulating ROW_NUMBER() analytic function. Records with the same value get the same rank.
SELECT company, plant, value
FROM
(
SELECT company, plant, value, #n := IF(#g = company, #n + 1, 1) rnum, #g := company
FROM table1 CROSS JOIN (SELECT #n := 0, #g := NULL) i
ORDER BY company, value DESC, plant
) q
WHERE rnum <= 3;
Output:
| COMPANY | PLANT | VALUE |
|---------|-------|-------|
| 1 | C | 5 |
| 1 | B | 4 |
| 1 | A | 3 |
| 2 | G | 6 |
| 2 | C | 5 |
| 2 | D | 3 |
| 3 | E | 8 |
| 3 | A | 7 |
| 3 | B | 3 |
Get all records per group that have a rank from 1 to 3 emulating DENSE_RANK() analytic function
SELECT company, plant, value
FROM
(
SELECT company, plant, value, #n := IF(#g = company, IF(#v = value, #n, #n + 1), 1) rnum, #g := company, #v := value
FROM table1 CROSS JOIN (SELECT #n := 0, #g := NULL, #v := NULL) i
ORDER BY company, value DESC, plant
) q
WHERE rnum <= 3;
Output:
| COMPANY | PLANT | VALUE |
|---------|-------|-------|
| 1 | C | 5 |
| 1 | B | 4 |
| 1 | A | 3 |
| 1 | E | 3 |
| 1 | G | 3 |
| 2 | G | 6 |
| 2 | C | 5 |
| 2 | D | 3 |
| 3 | E | 8 |
| 3 | A | 7 |
| 3 | B | 3 |
| 3 | G | 3 |
Here is SQLFiddle demo
UPDATE: Now it looks like HANA supports analytic functions so the queries will look like
SELECT company, plant, value
FROM
(
SELECT company, plant, value,
ROW_NUMBER() OVER (PARTITION BY company ORDER BY value DESC) rnum
FROM table1
)
WHERE rnum <= 3;
SELECT company, plant, value
FROM
(
SELECT company, plant, value,
DENSE_RANK() OVER (PARTITION BY company ORDER BY value DESC) rank
FROM table1
)
WHERE rank <= 3;
Here is SQLFiddle demo It's for Oracle but I believe it will work for HANA too
I want to get range ranking from a table using mysql query.
the table is like this,
+------------+------+
| first_name | age |
+------------+------+
| Kathy | 2 |
| Jane | 1 |
| Nick | 3 |
| Bob | 5 |
| Anne | 4 |
| Jack | 6 |
| Bill | 8 |
| Steve | 7 |
+------------+------+
and I want to get Jack's ranking with 2 lower and upper rankers.
+------------+------+
| Anne | 4 |
| Bob | 5 |
| Jack | 6 |
| Steve | 7 |
| Bill | 8 |
+------------+------+
Any idea how to write this query for a MySQL database?
Here is a very ugly way to do this by applying a rownumber to the records. By applying the rownumber to the records, then you you will be able to return rows if the ages are not consecutive (Demo with Non-consecutive ages):
select age, first_name
from
(
select t1.age, t1.first_name, #rownum:=#rownum+1 AS rownum
from yourtable t1, (SELECT #rownum:=0) r
order by t1.age
) x
where rownum >= (select rownum
from
(
select t.age,
t.first_name,
#rownum:=#rownum+1 AS rownum
from yourtable t, (SELECT #rownum:=0) r
order by t.age
) x
where first_name = 'jack') - 2
and rownum <= (select rownum
from
(
select t.age,
t.first_name,
#rownum:=#rownum+1 AS rownum
from yourtable t, (SELECT #rownum:=0) r
order by t.age
) x
where first_name = 'jack') + 2;
see SQL Fiddle with Demo
Working Example:
SELECT * FROM yourtable WHERE id BETWEEN ((SELECT id FROM yourtable WHERE name = 'Jack') - 2) AND ((SELECT id FROM yourtable WHERE name = 'Jack') + 2);
SQL Fiddle Demo