Given a series of email addresses, I need to randomly pair them with the condition that if A is to give a gift to B, then B must give a gift to A. If the number of email addresses is odd, the last three must be paired with each other (A with B, B with C, and C with A). I’m implementing this in MySQL with the following code:
CREATE TABLE IF NOT EXISTS CasoB(
id INT PRIMARY KEY AUTO_INCREMENT,
persons VARCHAR(50),
personsToGive VARCHAR(50)
);
INSERT INTO CasoB (persons, personsToGive) VALUES
('a.tomas', NULL),
('g.rubio', NULL),
('a.pulido', NULL),
('m.fabrega.1', NULL),
('d.lazaro', NULL),
('c.albinya', NULL),
('b.gomez', NULL),
('j.espinoza', NULL),
('j.aguilera', NULL),
('j.da.silva.1', NULL),
('a.chamorro', NULL);
DELIMITER //
CREATE OR REPLACE PROCEDURE GenerateRandomOrderB()
BEGIN
DECLARE lineCount INT;
-- Drop the temporary table if it exists
DROP TEMPORARY TABLE IF EXISTS RandomOrderB;
-- Create the temporary table
CREATE TEMPORARY TABLE IF NOT EXISTS RandomOrderB (
id INT PRIMARY KEY,
persons VARCHAR(50),
RowNumber INT,
TotalCount INT
);
-- Get the number of lines in CasoB
SELECT COUNT(*) INTO lineCount FROM CasoB;
-- Insert data into the temporary table and get the total count
INSERT INTO RandomOrderB (id, persons, RowNumber, TotalCount)
SELECT id,
persons,
ROW_NUMBER() OVER(ORDER BY RAND()) AS RowNumber,
lineCount AS TotalCount
FROM CasoB;
IF lineCount % 2 = 0 THEN
-- Even number of records
-- Pair the persons
UPDATE CasoB
SET personsToGive = (
SELECT r2.persons
FROM RandomOrderB AS r1
INNER JOIN RandomOrderB AS r2
ON r2.RowNumber = r1.RowNumber + (lineCount / 2)
WHERE r1.id = CasoB.id
);
ELSE
-- Odd number of records
-- Pair all persons except the last three
UPDATE CasoB
SET personsToGive = (
SELECT r2.persons
FROM RandomOrderB AS r1
INNER JOIN RandomOrderB AS r2
ON r2.RowNumber = r1.RowNumber + (lineCount / 2)
WHERE r1.id = CasoB.id
);
-- Pair the last three persons among themselves
UPDATE CasoB
SET personsToGive = persons
WHERE id IN (
SELECT id
FROM (
SELECT id
FROM RandomOrderB
ORDER BY RowNumber DESC
LIMIT 3
) AS lastThree
);
END IF;
-- Drop the temporary table when finished
DROP TEMPORARY TABLE IF EXISTS RandomOrderB;
END //
DELIMITER ;
New contributor
chamorro is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1