這是一個非常好,非常具有挑戰性的SQL問題。
你有一個非常具有挑戰性的一系列要求: 1.無matched_id應該不止一次出現在結果集中 2.沒有ID被賦予兩個以上的比賽 3.匹配是隨機的
我們將堅持純粹的SQL解決方案,假設您不能返回更大的結果集,並使用您的實現語言中的業務邏輯進行篩選。
首先,我們來解決隨機分配問題。隨機排列組內的項目是一個有趣的問題。我決定通過對行中數據的SHA1散列(id,follow_up,matched_id)進行排序來解決這個問題,這會給出具有隨機感的可重複結果。 (如果有包含創建或修改的日期/時間列這將是最好的。)
SELECT * FROM
(
SELECT
a.id,
a.follow_up,
a.matched_id,
a.rank_hash,
count(*) rank
FROM
(SELECT *, SHA1(CONCAT(id, follow_up, matched_id)) rank_hash FROM TableA) a
JOIN
(SELECT *, SHA1(CONCAT(id, follow_up, matched_id)) rank_hash FROM TableA) b
ON a.rank_hash >= b.rank_hash
AND a.id = b.id
GROUP BY a.id, a.matched_id
ORDER BY a.id, rank
) groups
WHERE rank <= 2
GROUP BY matched_id
如果有每個ID足夠matched_id值,這可能足以滿足您的使用案例。但是,如果存在隱藏的第四個要求會怎麼樣: 4.如果可能,一個ID應該收到一個匹配。
換句話說,如果隨機洗牌的結果,matched_id被分配到的ID有幾個其他比賽中,但進一步下跌的結果集,這是唯一的比賽一個ID是什麼?每個ID都與matched_id匹配的最佳解決方案是可能的,但它從未發生過,因爲所有matched_ids在流程的早期用完了?
例如:
CREATE TABLE TableA
(`id` int, `follow_up` int, `matched_id` varchar(1))
;
INSERT INTO TableA
(`id`, `follow_up`, `matched_id`)
VALUES
(1, 10, 'A'),
(1, 10, 'B'),
(1, 10, 'C'),
(2, 5, 'D'),
(2, 5, 'E'),
(2, 5, 'F'),
(3, 5, 'C')
;
在上述組中,如果ID和它們的匹配被隨機分配的,如果ID 1被分配matched_id C,然後ID 3不會得到一個matched_id在所有。
如果我們首先找出有多少匹配收到的ID,然後按順序排序呢?
SELECT
a.*,
frequency
FROM TableA a
JOIN
(SELECT
matched_id,
count(*) frequency
FROM
TableA
GROUP BY matched_id
) b
ON a.matched_id = b.matched_id
GROUP BY a.matched_id
ORDER BY b.frequency
這是一箇中間人編程語言可能派上用場,幫助限制結果集。
但請注意,我們也失去了我們對隨機性的要求!正如你所看到的,一個純粹的SQL解決方案可能會非常難看。確實可以結合上述技術。
希望這會讓你的想象力開火。
爲什麼需要這樣的結果? –
,因爲我需要運行病例對照研究來查找控制人員,這些人員是在醫院中與患有疾病的病例相匹配的患者,並給出一些匹配條件。在我給出了一些條件之後,我有一個類似於上面的表格,但有一個控件匹配超過1個案例 – emisu
因此,考慮到上面的數據集,可用結果的範圍實際上非常有限?這基本上是人類數獨。而follow_up基本上與這個問題無關,對吧? – Strawberry