Re: SQL question
Date: 2000/05/13
Message-ID: <8fjvog$13u$1_at_nnrp1.deja.com>#1/1
>> My database contains information about "samples" that are stored in
"racks". Every "rack" has a capacity ("size"). The positions in a rack
are numbered. A rack does not have to be filled in sequentially, i.e.
there may be a sample at position 3 and one at position 11 while the
rest of the rack remains empty. <<
Let me clean up your tables and write them in SQL instead of your personal pseudo-code:
CREATE TABLE Samples
(sample_id INTEGER NOT NULL PRIMARY KEY,
rack_nbr INTEGER NOT NULL
REFERENCES Racks(rack_nbr),
position_in_rack INTEGER NOT NULL
CHECK (position_in_rack > 0));
CREATE TABLE Racks
(rack_nbr INTEGER NOT NULL PRIMARY KEY,
size INTEGER NOT NULL
CHECK (size > 0));
>> My question: how can I retrieve a list of all free positions in a
certain rack? <<
Sure, this is the "gaps" problem. But you have to make one of two changes:
- give up the idea of one row per rack position and get the start and stop rack positions of the gaps
SELECT R1.rack_nbr,
S1.position_in_rack AS gap_start,
MIN(S2.position_in_rack - 1) AS gap_end
FROM Racks AS R1, Samples AS S1, Samples AS S2
WHERE R1.rack_nbr = S1.rack_nbr
AND R1.rack_nbr = S2.rack_nbr
AND S1.rack_nbr <= S2.rack_nbr
AND S1.position_in_rack + 1
BETWEEN 1 AND R1.size
AND S2.position_in_rack - 1
BETWEEN 1 AND R1.size
AND S1.position_in_rack + 1
NOT IN (SELECT position_in_rack
FROM Samples AS S3
WHERE S3.rack_nbr = S1.rack_nbr)
AND S1.position_in_rack - 1
NOT IN (SELECT position_in_rack
FROM Samples AS S4
WHERE S4.rack_nbr = S1.rack_nbr)
GROUP BY R1.rack_nbr, S1.position_in_rack;
I just got home and have not checked this code, so be careful. I have this problem in SQL FOR SMARTIES.
2) Build an auxiliary table of sequential numbers to find the missing numbers; this is more of what you wanted, I think.
CREATE TABLE Sequence (i INTEGER NOT NULL PRIMARY); INSERT INTO Sequence VALUES (1), (2), ... , (n);
SELECT R1.rack_nbr, Q1.i AS missing_position
FROM Racks AS R1
WHERE NOT EXISTS
(SELECT *
FROM Samples AS S1, Sequence AS Q1
WHERE Q1.i = S1.position_in_rack
AND Q1.i <= R1.size
AND S1.rack_nbr = R1.rack_nbr);
--CELKO--
Joe Celko, SQL and Database Consultant
Sent via Deja.com http://www.deja.com/
Before you buy.
Received on Sat May 13 2000 - 00:00:00 CEST
