Reputation:
I have a table containing values like the following:
"things"
+ FirstOctet + SecondOctet +
| 0 | 0 |
| 0 | 1 |
| 1 | 0 |
| 1 | 0 |
+------------+-------------+
Essentially, FirstOctet
and SecondOctet
contain values that range form 0-255. The rows are in no particular order. I want to query the database to get the next available value within the table, based on the lowest FirstOctet
and SecondOctet
. There are no duplicate values for FirstOctet AND SecondOctet (if that makes sense).
So, if the table looks something like:
"things"
+ FirstOctet + SecondOctet +
| 1 | 0 |
| 1 | 4 |
| 1 | 1 |
| 1 | 3 |
+------------+-------------+
I'd like it to find that the next available values are FirstOctet=1
and SecondOctet=2
.
All I have so far is just a pretty simple query to tally up the first octets, and that have a count under 255.
select
*, count(*) as count
from
things
group by first_octet
having count < 255
order by first_octet
I have no idea where to go from here. I'm thinking that once I find rows where FirstOctet < 255, it MUST have an available row. Where do I go from here?
Upvotes: 0
Views: 297
Reputation: 2015
Working demo: http://sqlfiddle.com/#!2/1e60c8/3
CREATE VIEW ViewBoolean AS SELECT 0 as b UNION SELECT 1 as b;
CREATE VIEW ViewByteValues AS
SELECT b0.b + b1.b*2 + b2.b*4 + b3.b*8 + b4.b*16 + b5.b*32 + b6.b*64 + b7.b*128 as v FROM
ViewBoolean b0,ViewBoolean b1,ViewBoolean b2,ViewBoolean b3,ViewBoolean b4,ViewBoolean b5,ViewBoolean b6,ViewBoolean b7;
-- above from covus corax, http://stackoverflow.com/questions/304461/generate-an-integer-sequence-in-mysql
CREATE VIEW ViewOctetPairs AS
SELECT octet1.v as octet1, octet2.v as octet2
FROM ViewByteValues AS octet1
CROSS JOIN
ViewByteValues AS octet2
WHERE octet1.v < 256
AND
octet2.v < 256
;
Create Table things
(Octet1 INT,
Octet2 INT)
;
Then the query is
SELECT * FROM ViewOctetPairs as allPairs
LEFT JOIN
things
ON allPairs.octet1 = things.octet1
AND allPairs.octet2 = things.octet2
WHERE things.octet1 IS NULL
ORDER BY allPairs.octet1 ASC, allPairs.octet2 ASC
LIMIT 1
The idea is - you create a 2 column "View", with every permutation of numbers. Then you join it against "things", selecting only the rows from the View that aren't in "things", then you choose the first one, where first means the lowest available first column, and if there's more than one, the lowest available second column within that column.
Upvotes: 2
Reputation: 6086
I try this:
select FirstOctet, SecondOctet + 1
from things t1
where not exists (select * from things t2 where t1.FirstOctet = t2.FirstOctet and
t1.SecondOctet + 1 = t2.SecondOctet)
and SecondOctet + 1 < 255
order by FirstOctet, SecondOctet
limit 1
Upvotes: 1