Это очень хороший и очень сложный вопрос SQL.
У вас есть очень сложный набор требований: 1. Ни matched_id не должно появляться более одного раза в результате установки 2. Нет ID не будет дано более двух матчей 3. Совпадение случайным
We будет придерживаться чистого 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
Это может быть достаточно для случая использования, если имеются достаточные значения matched_id для каждого идентификатора. Но что, если есть скрытое четвертое требование: 4. Если возможно, идентификатор должен получить соответствие.
Другими словами, что, если в результате случайного перетасовки соответствие идентификатора сопоставлено идентификатору, имеющему несколько других совпадений, но дальше по результату результат был равен для идентификатора? Было возможно оптимальное решение, в котором каждый идентификатор был сопоставлен с matched_id, но этого не произошло, потому что все сопоставленные_иды были использованы ранее в этом процессе?
Например:
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 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 может стать довольно уродливым. Это действительно возможно, объединяя методы, описанные выше.
Надеюсь, это вызовет ваше воображение.
Зачем вам нужен этот результат? –
, потому что мне нужно запустить исследование контроля над заболеванием, чтобы найти элементы управления, которые являются пациентами в больнице, которые соответствуют случаям с болезнью, при определенных условиях. После того, как я дал некоторые условия, у меня есть таблица, аналогичная приведенной выше, но есть элементы управления, которые соответствуют более чем одному случаю – emisu
Итак, учитывая приведенные выше данные, диапазон допустимых результатов на самом деле очень ограничен? Это в основном человеческая судоку. И follow_up в основном не имеет отношения к этой проблеме, не так ли? – Strawberry