给定一系列电子邮件地址,我需要将它们随机配对,条件是如果A要给B送礼物,那么B必须给A送礼物。如果电子邮件地址的数量是奇数,则后三个必须彼此配对(A 与 B、B 与 C、C 与 A)。我使用以下代码在 MySQL 中实现此功能:
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 ;
我的问题,我认为代码是正确的,至少随机化偶数的部分是这样的
DROP TABLE IF EXISTS RandomOrder;
CREATE TEMPORARY TABLE IF NOT EXISTS RandomOrder (
id INT PRIMARY KEY,
people VARCHAR(50),
RowNumber INT,
TotalCount INT
);
INSERT INTO RandomOrder (id, people, RowNumber, TotalCount)
SELECT
id,
people,
ROW_NUMBER() OVER(ORDER BY RAND()) AS RowNumber,
COUNT(*) OVER() AS TotalCount
FROM CaseA;
UPDATE CaseA
SET peopleForGift = (
SELECT r2.people
FROM RandomOrder AS r1
INNER JOIN RandomOrder AS r2
ON r2.RowNumber = (r1.RowNumber % r1.TotalCount) + 1
WHERE r1.id = CaseA.id
);
但是当涉及到将其随机化为奇数人时,首先对除最后3人之外的所有人进行随机化,然后仅对这3人进行随机化但是当涉及到将其随机化到奇数人时,进行随机化首先是除了最后 3 个人之外的所有人,然后仅随机化这 3 个人
WITH
cte1 (id, persons, personsToGive, rn) AS (
SELECT id, persons, personsToGive,
ROW_NUMBER() OVER (ORDER BY RAND())
FROM CasoB
),
cte2 (id, persons, personsToGive, rn, rnx) AS (
SELECT id, persons, personsToGive, rn,
CASE WHEN 0 = (SELECT COUNT(*) MOD 2 FROM CasoB)
THEN ((rn + 1) DIV 2) * 4 - 1 - rn
ELSE CASE WHEN rn > 3
THEN (rn DIV 2) * 4 + 1 - rn
ELSE (rn MOD 3) + 1
END
END
FROM cte1
)
UPDATE CasoB
JOIN cte2 cte21 ON CasoB.id = cte21.id
JOIN cte2 cte22 ON cte21.rn = cte22.rnx
SET CasoB.personsToGive = cte22.persons;