This is my sample data
CREATE TABLE customer1
(
rating int(9),
genre varchar(100),
title varchar(100)
);
INSERT INTO customer1 (rating, genre, title)
VALUES
(2, 'A', 'abc'),
(4, 'A', 'abc1'),
(2, 'B', 'abc2'),
(3, 'B', 'abc3'),
(2, 'C', 'abc4'),
(5, 'C', 'abc5');
I need to find the title with max rating in each genre.
Thanks for the help.
One option uses a subquery for filtering:
select c.*
from customer1
where c.rating = (select max(c1.rating) from customer1 c1 where c1.genre = c.genre)
This would take advantage of an index on (genre, rating).
In MySQL 8.0, you can also use window functions:
select *
from (
select c.*,
rank() over(partition by genre order by rating desc) rn
from customer1 c
) c
where rn = 1
Related
I have a table like this:
groupX groupY quantity
A B 10
A C 2
C D 7
B A 13
C B 1
D B 9
So, the same individuals appear at columns groupX and groupY. I would like to write a Select that makes the following:
Select
(Select groupX, sum(quantity) group by groupX) as M
- (Select groupY, sum(quantity)
group by groupY) as N
ORDER BY M-N Desc
I mean, I need to sum the quantities for each individual when they appear at groupX and when they appear at groupY and then calculate the difference for each individual between first and second quantity. Finally I need the query to order the individuals by that difference.
Of course the query I wrote does not work.
With this table as source
CREATE TABLE tableA
(`groupX` varchar(1), `groupY` varchar(1), `quantity` int)
;
INSERT INTO tableA
(`groupX`, `groupY`, `quantity`)
VALUES
('A', 'B', 10),
('A', 'C', 2),
('C', 'D', 7),
('B', 'A', 13),
('C', 'B', 1),
('D', 'B', 9)
;
You get with this statement
SELECT T1.groupX groupname, (sum1 - sum2) as res
From
(SELECT groupX ,Sum(quantity) sum1 From tableA Group by groupX) T1
inner join (SELECT groupY,Sum(quantity) sum2 From tableA Group by groupY) T2
On T1.groupX = T2.groupY
ORDER by res;
You will get
groupname res
B -7
A -1
D 2
C 6
As i don't know all your data, it can be that it is better ti use Left join, which would include all unique memebers of groupX that have no corresponding group in groupY.
With right join it is vice versa
See example here https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=6c2facaaf6564d4025f24f6aab35adf7
I have this script and it works in SQL Server 2012, but I need to use it in SQL Server 2008. Does anyone have a suggestion ?
Create table #TempOne (ID int)
Insert into #TempOne
Values (1), (2), (34), (121), (72), (34), (81), (26), (234)
Create table #TempTwo
(
ID int,
Name Varchar(30),
Age int
)
Insert into #TempTwo
Values (18, 'P', 291), (11, 'P', 21), (13, 'P', 11), (21, 'P', 21)
Select
LEAD(ID,3) Over(Order By ID) As ID, Name , Age
From
(Select ID, NULL As Name, NULL As Age
From #TempOne
Union
Select NULL, Name, age
From #TempTwo) a
Your query would look something like the following:
WITH a AS (
Select ID , NULL As Name,NULL As Age
From #TempOne
Union
Select NULL, Name,age From #TempTwo
),
an AS (
SELECT
*,
rn=ROW_NUMBER() OVER (ORDER BY ID)
FROM
a
)
SELECT
an_r.ID,an_l.Name,an_l.Age
FROM
an AS an_l
LEFT JOIN an AS an_r ON
an_r.rn=an_l.rn+3;
What this does, is first number the rows using ROW_NUMBER, ordered by ID. In that case, LEAD(ID,3) can be done by self-joining the numbered set on right-rn=left-rn+3.
I have a simple table
CREATE TABLE `example` (
`id` int(12) NOT NULL,
`food` varchar(250) NOT NULL
);
With the following data
INSERT INTO `example` (`id`, `food`) VALUES
(1, 'apple'),
(2, 'apple'),
(3, 'apple'),
(4, 'apple'),
(5, 'apple'),
(6, 'apple'),
(7, 'apple'),
(8, 'banana'),
(9, 'banana'),
(10, 'potato'),
(11, 'potato'),
(12, 'potato'),
(13, 'banana'),
(14, 'banana'),
(15, 'banana');
I want to get the oldest 10 rows
SELECT *
FROM example
ORDER BY id ASC
LIMIT 10
But I don't want to get more than 5 rows where food has the same value.
My current query receives 7 apple (more than I want), 2 banana, and 1 potato. In the data provided, I'd want to receive 5 apple, 2 banana, and 3 potato.
How can I accomplish this?
Update:
SQL Group BY, Top N Items for each Group is not a duplicate because it involves a different database. In particular, GROUP BY works different in sql-server than it does in MySQL
You can add a count (in reverse) for each food . . . using variables or a correlated subquery. This will use the latter:
select t.*
from (select t.*,
(select count(*) from example t2 where t2.food = t.food and t2.id >= t.id) as seqnum
from example t
) t
where seqnum <= 5
order by id desc
limit 10;
I didn't create the table and test this, but it should give you what you want. Just a different approach than the one above.
Select *
From (Select ID, Food
, Count(Food) Over(Partition By Food Order by ID) as Appearances
From Your_Table) as a
Where a.Appearances <= 5
Order By ID Asc
You can obviously put the limit if you want.
I have two tables myTable and myTable2 in a mysql database:
CREATE TABLE myTable (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
number INT,
version INT,
date DATE
) ENGINE MyISAM;
INSERT INTO myTable
(`id`, `number`, `version`, `date`)
VALUES
(1, '123', '1', '2016-01-12'),
(2, '123', '2', '2016-01-13'),
(3, '124', '1', '2016-01-14'),
(4, '124', '2', '2016-01-15'),
(5, '124', '3', '2016-01-16'),
(6, '125', '1', '2016-01-17')
;
CREATE TABLE myTable2 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
myTable_id INT
) ENGINE MyISAM;
INSERT INTO myTable2
(`id`, `myTable_id`)
VALUES
(1, 1),
(2, 1),
(3, 2),
(4, 2),
(5, 3),
(6, 3),
(7, 4),
(8, 4),
(9, 4),
(10, 5),
(11, 6)
;
The field myTable2.myTable_id is a foreign key of myTable.Id.
I would like to get all the rows from myTable where myTable2.myTable_id = myTable.Id and the value of the field version in myTable is the maximum for every corresponding value for the field number in myTable.
I tried something like this:
SELECT
*
FROM
myTable,
myTable2
WHERE
myTable.version = (SELECT MAX(myTable.version) FROM myTable)
But the above query does not return the correct data. The correct query should output this:
Id number version date
2 123 2 2016-01-13
5 124 3 2016-01-16
6 125 1 2016-01-17
Please help!
One way to do this is to get the max version for each number in myTable in a derived table and join with that:
SELECT DISTINCT
m.*
FROM
myTable m
JOIN
myTable2 m2 ON m.id = m2.myTable_id
JOIN
(
SELECT number, MAX(version) AS max_version
FROM myTable
GROUP BY number
) AS derived_table
ON m.number = derived_table.number
AND m.version = derived_table.max_version
With your sample data this produces a result like this:
id number version date
6 125 1 2016-01-17
5 124 3 2016-01-16
2 123 2 2016-01-13
your Query is logically wrong. Here is the correct one
SELECT
*
FROM
myTable,
myTable2
WHERE
(myTable.version,myTable.number) in
(SELECT MAX(myTable.version),number FROM myTable group by number)
and myTable.id=myTable2.id
Here is the sqlfiddle http://sqlfiddle.com/#!9/74a67/4/0
This is the query posted for the previous edited question
SELECT * FROM myTable
inner join myTable2 on myTable.id = myTable2.mytable_id
WHERE (version, number) in
(SELECT MAX(version), number FROM myTable group by number)
Try this solution with using subquery simply as:
# Selecting desired result..
SELECT t1.id, t1.number, t1.version, t1.date
FROM myTable As t1 JOIN
# subquery to select max version and its corresponding
# number form myTable
(SELECT number, max(version) As max_ver FROM myTable
GROUP BY number
) As t2 ON t1.number = t2.number and t1.version = t2.max_ver
# Now checking for foreign key..
WHERE t1.id IN (SELECT mytable_id FROM myTable2);
Was it helpful..
What is wrong with this query?
SELECT *, (SELECT COUNT(*)
FROM
(
SELECT NULL
FROM words
WHERE project=projects.id
GROUP BY word
HAVING COUNT(*) > 1
) T1) FROM projects
MySQL returns 1054 Unknown column 'projects.id' in 'where clause'
Thanks
Does this work?
SELECT *, (SELECT COUNT(*)
FROM words
WHERE words.project=projects.id) as pCount
FROM projects
Your inner subquery knows nothing about the outer query, so the projects table is not available.
It looks like you are trying to count for each project the number of words which occur more than once.
You can run your subquery for all projects and then use a JOIN to get the rest of the data from the projects table:
SELECT projects.*, COUNT(word) AS cnt
FROM projects
LEFT JOIN (
SELECT project, word
FROM words
GROUP BY project, word
HAVING COUNT(*) > 1
) T1
ON T1.project = projects.id
GROUP BY projects.id
Result:
id cnt
1 0
2 1
3 2
Test data:
CREATE TABLE projects (id INT NOT NULL);
INSERT INTO projects (id) VALUES (1), (2), (3);
CREATE TABLE words (project INT NOT NULL, word VARCHAR(100) NOT NULL);
INSERT INTO words (project, word) VALUES
(1, 'a'),
(2, 'a'),
(2, 'b'),
(2, 'b'),
(3, 'b'),
(3, 'b'),
(3, 'c'),
(3, 'c');