SQL - Selecting all or none in a set of rows - mysql

I have a table where multiple entries are grouped by having the same number. Each of these rows also have a result.
Example
id 4 | Group 5 | Result 1
id 5 | Group 5 | Result 1
id 6 | Group 6 | Result 0
id 7 | Group 6 | Result 1
How would I go about selecting the highest number group where all their result is the same number?
In otherwords, say I want to get the highest group where result = 1; I would not want group 6 as there is a result is 0, nor would I want any groups older than group 4 as all of group 5 have a result of 1.

There's a couple of different ways to do this. Here's one approach to select the highest group using order by and limit where all results are 1 using max and min:
select grp
from yourtable
group by grp
having max(result) = 1 and min(result) = 1
order by grp desc
limit 1

This is a slightly dierent approach.
SELECT `group` FROM `test`
GROUP BY `group`
HAVING COUNT(`result`)=SUM(`result`) AND SUM(`result`)>0
ORDER BY `group` DESC LIMIT 1;
Check it on SQL Fiddle

Related

Get the duplicate rows with the number of occurrence in MYSQL

I need to list all the duplicate IDs with the number of occurrence of each ID in a single MYSQL query.
ID
____
1
1
2
3
4
4
4
5
5
6
7
Output must be:
ID | Occurrence
_______________
1 | 2
4 | 3
5 | 2
Just use a simple GROUP BY query:
SELECT ID, COUNT(*) AS Occcurrence
FROM yourTable
GROUP BY ID
HAVING COUNT(*) > 1
This can be done simply by using Group By clause and Count() function
select
Id, count(id) as Occurance
from
tableName
group by id
having Occurance > 1;
use mysql GROUP BY
select ID,count(*) from table_name group by ID having count(*) > 1

MYSQL - having count(*) without group by

I have a MySQL table
discount_vouchers
------------------
id
email
test_id
My goal is to list all vouchers that appears more than once with a given email and a given test_id from the GROUP BY:
GROUP BY email, test_id
HAVING count(*) >1
How to get read of this group by?
Here is an example:
discount_vouchers
------------------
1 1#test.com 20
2 1#test.com 10
3 1#test.com 20
4 2#test.com 30
I would like to have as a result:
id email test_id count
1 1#test.com 20 2
2 1#test.com 10 1
3 1#test.com 20 2
4 2#test.com 30 2
Try something like the following
SELECT C2, counter from
(SELECT C2, COUNT(*) as counter FROM test.mytable
GROUP BY C2) as aggregation
WHERE counter > 1
Without using group by, you can do something like
SELECT a.* ,
(SELECT count(*) FROM discount_vouchers b
WHERE a.email = b.email AND a.test_id = b.test_id) as count
FROM discount_vouchers a
How about this?
Aggregate using a subquery, and use its results in order to enrich the actual table:
SELECT `discount_vouchers`.*, `counts`.`count`
FROM `discount_vouchers`
INNER JOIN (SELECT `email`, `test_id`, Count(*) AS 'count'
FROM `discount_vouchers`) AS `counts`
ON `discount_vouchers`.`email` = `counts`.`email`
AND `discount_vouchers`.`test_id` = `counts`.`test_id`;

Select the first 5 rows and get count

I'm trying to write a mysql query:
first select 5 rows and then get count with a where
first select 5 rows
table
id user_id
--------
1 1
2 2
3 3
4 1
5 1
6 4
7 3
8 1
id user_id
----------
1 1
2 2
3 3
4 1
5 1
And then get count this table where user_id =1
result = 3
You can try somthing like that
Select count(*) From
(Select * From T
order by ID asc Limit 5) as child
where user_id = 1
Looks like you want to present two different result sets together. You need to use a JOIN for this. Something like so will do the trick for you.
SELECT T.*,c.cnt
FROM T
JOIN ( SELECT COUNT(*) cnt FROM T where user_id = 1 ) c
LIMIT 5
The subquery generates your count as a one-row resultset, and the JOIN (which lacks an ON condition) puts it into every row of your other resultset.
If you wanted to show five rows from your table, and have each row mention the count for the userid in that row, you could do this.
SELECT T.*,c.cnt
FROM T
JOIN ( SELECT COUNT(*) cnt, user_id
FROM T
GROUP BY user_id
) c ON T.user_id = c.user_id
LIMIT 5
The way that summary (COUNT(), etc) queries and detail queries work together is a little intricate, but you will figure it out.
Beware, though: If you do a LIMIT without first doing an ORDER BY, MySQL is free to return any five rows it pleases.

Limit number of rows returned ORDER BY

I want to limit the number of rows returned when using a statement with an ORDER BY clause.
One of my columns has an ID not unique to the row and so appears multiple times. If I use a LIMIT at the end of the statement it would limit the results entirely, not at the SELECT point. The LIMIT might be 3, in which case three rows for each ID would be returned.
id | .........
1 | .........
1 | ........
1 | .......
1 | ......
1 | .....
2 | ....
2 | ...
2 | ..
2 | .
The end of my statement has:
ORDER BY id, date DESC
Here is one method:
select t.*
from table t
where (select count(*)
from table t2
where t2.id = t.id and t2.date >= t.date
) <= 3
order by id, date desc;
This counts the number of dates for an id that are equal to or larger than the date in a row, and only keeps the rows where the count is less than or equal to 3.

How can I select adjacent row in sql when ordered by a different field?

I've got a table of data with the following structure:
id | likes
1 | 2
2 | 5
3 | 2
4 | 6
5 | 2
If want to find the row next to #3 I can use :
SELECT * FROM table WHERE id >= 3 ORDER BY id
However what I want to do is order by table by likes. When the data is ordered by likes it looks like this
id | likes
1 | 2
3 | 2
5 | 2
2 | 5
4 | 6
How can I select the rows before or after a certain id when ordered by likes?
e.g. for id 5, my result would be row id 3 before and row id 2 after.
If likes are unique numbers, following should work.
previous:
SELECT * FROM table WHERE likes < (SELECT likes FROM table WHERE id = ID) ORDER BY likes DESC LIMIT 1
next:
SELECT * FROM table WHERE likes > (SELECT likes FROM table WHERE id = ID) ORDER BY likes ASC LIMIT 1
You may change 1 of them to <= or >= and add WHERE id != ID
Your second table shows wrong ids for the first two rows, by the way.
It should be:
id likes
1 2
3 2
This works in MySQL for me:
Select id, likes from (SELECT id, #rownum:=#rownum+1 AS rownum, likes
FROM table u, (SELECT #rownum:=0) r ORDER BY likes) as derived where
rownum >= 2 and rownum <= 4;
(SELECT id, #rownum:=#rownum+1 AS rownum, likes FROM table u, (SELECT
#rownum:=0) r ORDER BY likes);
The last part tries to simulate the row number, which is missing in MySQL, but available in MSSQL, Oracle and others.