How to find out next available number - mysql

In my MySQL table I have field called sequence where I have values like
1 , 2, 3, 5, 6, 7, 8, 10 some of the sequence number are skiped due to deleted records. How do I find out next available number from given number. let's say if I need next number from 3 , how do I get number 5 as my next number in sequence not the 4.

To find out the next ID after 3 that appears in your table, you should do
SELECT id FROM thetable WHERE id>3 ORDER BY id ASC LIMIT 1
This just considers IDs that are greater than 3, in ascending order, and then takes the first one on that list. If it returns you one result, then that's the next one used in the table; if it doesn't return a result at all, then the ID you gave it was already the highest one in the table (or, strictly speaking, at least as high as the highest one in the table).

If you want a general expression that works to get the next available number, then you can use an aggregation query:
select coalesce(max(id), maxid + 1) as NextAvailableId
from table t cross join
(select max(id) as maxid from table t) x
where id > 3;
Or, if you don't like the cross join, you can use conditional aggregation:
select coalesce(max(case when id > 3 then id end), max(id)) as NextAvailableId
from table t;

Related

MySQL: Show row number in SELECT query output

I have a table in a MySQL database. I want to display the item number (not the primary key) and then a row number.
item_num, row_number
1, 1
12, 2
1234, 3
15, 4
29, 5
Here is my query:
select item_num, row_number() over(partition by item_num) from items;
My output is this:
item_num, row_number
1, 1
12, 1
1234, 1
15, 1
29, 1
How can I fix this issue and show the correct row number for each item?
Answer
The following query should create the behaviour you want:
SELECT item_num, ROW_NUMBER() OVER() FROM items;
Explanation
The ROW_NUMBER() formula sequentially numbers the rows of each partition which is passed into it. It begins again at 1 for each partition, independently. Therefore, attempting to partition the database by item_num before using ROW_NUMBER() will result in each unique item_num being assigned a row number of 1.
Instead, use a blank OVER() clause. There's no need to partition the database or order it in any specific way, since you simply want to apply ROW_NUMBER() based on the order already present in the database.

searching for records in mysql using or - and - not in query

I think I am getting turned around when looking at this. I am trying to get all patron records relating to transactions that have a transaction item with one of a number of ids (1 or 2) as well as transaction items with other ids (3 or 4) but not with transaction items with other ids (5 or 6)
The structure is:
=patron=
id
fname
lname
email
phone
=trans=
id
id_org
id_patron
=trans_item=
id
id_trans
id_perf
I was trying the following:
SELECT
patron.email,
patron.fname,
patron.lname,
patron.phone
FROM
trans_item,
trans,
patron
WHERE
trans_item.id_perf IN (1,2)
AND
trans_item.id_perf IN (3,4)
AND
trans_item.id_perf NOT IN (5,6)
AND
trans_item.id_trans = trans.id
AND
trans.id_org = 1
AND
trans.id_patron = patron.id
GROUP BY
patron.id
ORDER BY
patron.email DESC,
patron.phone DESC
I'm aware that saying the id needs to be 2 AND 4 is always going to return nothing but I need to have it as if id is in (1,2) AND (3,4) so it can be 1 or 2 but also needs to be in 3 or 4
For Clarity:
I am trying to get patrons who have gone to performance 1 OR 2 and 3 OR 4 but NOT 5 OR 6
You can do this with group by and having. The basic idea is:
select ti.id_trans
from trans_item ti
group by ti.id_trans
having sum(ti.id_perf in (1, 2)) > 0 and
sum(ti.id_perf in (3, 4)) > 0 and
sum(ti.id_perf in (5, 6)) = 0;
Each condition in the having clause checks a row for the particular ids. The > 0 means they exist for transaction. The = 0 means they do not.
If you want additional columns from other tables, you can join back to this result set.
I think I have a solution. If I combine the ids for all perfs and group all results by the trans_item.id I can get a list that has duplicates. I then convert them into a php multidimensional array and exclude / include based on the ids for each requirement finding the duplicates that way. Any other suggestions are welcome

how can I tell if the last x rows of 'state' = 1

I need help with a SQL query.
I have a table with a 'state' column. 0 means closed and 1 means opened.
Different users want to be notified after there have been x consecutive 1 events.
With an SQL query, how can I tell if the last x rows of 'state' = 1?
If, for example, you want to check if the last 5 consecutive rows have a state equals to 1, then here's you could probably do it :
SELECT IF(SUM(x.state) = 5, 1, 0) AS is_consecutive
FROM (
SELECT state
FROM table
WHERE Processor = 3
ORDER BY Status_datetime DESC
LIMIT 5
) as x
If is_consecutive = 1, then, yes, there is 5 last consecutive rows with state = 1.
Edit : As suggested in the comments, you'll have to use ORDER BY in your query, to get the last nth rows.
And for more accuracy, since you have a timestamp column, you should use Status_datetime to order the rows.
You should be able to use something like this (replace the number in the HAVING with the value of x you want to check for):
SELECT Processor, OpenCount FROM
(
SELECT TOP 10 Processor, DateTime, Sum(Status) AS OpenCount
FROM YourTable
WHERE Processor = 3
ORDER BY DateTime DESC
) HAVING OpenCount >= 10

Counting rows in mysql database

I want to count from the row with the least value to the row with a specific value.
For example,
Name / Point
--------------------
Pikachu / 7
Voltorb / 1
Abra / 4
Sunflora / 3
Squirtle / 8
Snorlax / 12
I want to count to the 7, so I get the returned result of '4' (counting the rows with values 1, 3, 4, 7)
I know I should use count() or mysql_num_rows() but I can't think of the specifics.
Thanks.
I think you want this :
select count(*) from mytable where Point<=7;
Count(*) counts all rows in a set.
If you're working with MySQL, then you could ORDER BY Point:
SELECT count(*) FROM table WHERE Point < 7 ORDER BY Point ASC
If you want to know all about ORDER BY, check out the w3schools page: http://www.w3schools.com/sql/sql_orderby.asp
Just in case you want to only count the rows based on the Point values:
SELECT count(*) FROM table WHERE Point < 7 GROUP BY Point
This may help you to get rows falling between range of values :
select count(*) from table where Point >= least_value and Point<= max_value

How can I fetch "partial matches" with mysql?

I need to find best matches from a mysql table given a set of attributes.
For example, given ATTRIBUTE1, ATTRIBUTE2 and ATTRIBUTE3, I want to get the results as follows:
rows with all attributes matched
rows with 2 attributes matched
rows with 1 attribute matched
so far I only know how to accomplish the first statement:
SELECT * FROM Users
WHERE ATTRIBUTE1="aValue", ATTRIBUTE2="aValue", ATTRIBUTE3="aValue"
LIMIT 20
N.B. I need 2 lists. A list with fully matching rows and a list with partial matches
you can consider to build an composite index in ATTRIBUTE{1..3}
this will benefits for List A
SELECT *
FROM Users
WHERE ATTRIBUTE1="aValue" AND ATTRIBUTE2="aValue" AND ATTRIBUTE3="aValue"
LIMIT 20
and might help some row in List B
SELECT *,
IF (ATTRIBUTE1="aValue", 1, 0) as a1,
IF (ATTRIBUTE2="aValue", 1, 0) as a2,
IF (ATTRIBUTE3="aValue", 1, 0) as a3
FROM Users
WHERE ATTRIBUTE1="aValue" OR ATTRIBUTE2="aValue" OR ATTRIBUTE3="aValue"
ORDER BY (a1+a2+a3) DESC
LIMIT 20