У меня есть таблица, которая содержит несколько ключей в другие таблицы (где каждый ключ состоит из нескольких столбцов). Я хотел бы иметь возможность группировать строки, имеющие одинаковый ключ, но я не хочу группировать их все вместе. Это не просто GROUP BY
по ключу, а скорее я хочу, чтобы можно было создать группы, скажем, 10. Так что, если конкретный ключ появлялся 50 раз, я получал бы 5 результатов при выполнении этой группировки (5 групп по 10). Я также хочу, чтобы эта группировка происходила случайным образом в ключе.
Я не знал о прямом способе сделать это, и метод обхода, который я придумал, не работает, как я думаю, что должен. Обходным решением, которое я придумал, было создание нового столбца для каждого ключа, который был бы целым числом, таким образом, что значение i
представляет ith
вхождение этого ключа (но в случайном порядке). Затем я мог бы сделать целочисленное деление, чтобы все n (скажем, 10) строк в ключе имели одинаковое значение, и я мог бы сделать для GROUP BY
этого значения.
Есть ли более прямой способ выполнить то, что я только что описал? Это довольно неловко, и я столкнулся с проблемами при создании нового столбца индекса (как я описал в этом вопросе ).
РЕДАКТИРОВАТЬ: Прежде всего, обратите внимание, что это для MySQL. Я добавлю пример, если моя цель не ясна. Документы MySQL показывают метод, чтобы добраться почти до цели :
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Это создает таблицу, которая, хотя и не то, что я хочу, приближается:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
По сути, я хотел бы GROUP BY
идентифицировать, за исключением того, что я хотел бы, чтобы записи mammal
имели одну «группу» для идентификаторов 1–10, другую «группу» для идентификаторов 11–20 и т. Д. Однако я бы делал это с существующей таблицей, и я бы не хотел, чтобы «собака» появлялась с идентификатором 1. Я бы хотел, чтобы этот первоначальный порядок был случайным, но затем детерминированным.
I would want that initial ordering to be random, but then deterministic from then out.
<- скажи что? Я думаю, что независимо от того, что вы делаете, вы должны будете поместить записи во вторую таблицу. Насколько точно работает эта бизнес-логика? Так как нет ничего, что требовало бы (например) собаки, чтобы прийти первым. И что вы подразумеваете подI would want the records from *mammal* to have one "group" for IDs 1-10, and another for IDs 11-20
... можете ли вы проиллюстрировать это другой таблицей, посвященной млекопитающим, в приведенном выше описании вопроса?numMammal
. Меня не волнует, чтоdog
получает id , но я не хочу, чтобы он зависел от исходного порядка вставки.GROUP BY
. Я мог бы тогда хотеть соединить группы из 10, чтобы найти корреляцию между средним. Мне нужен этот случайный порядок, потому что если бы исходный порядок вставки был отсортирован по весу, это дало бы мне неверные результаты. Я надеюсь, что я понимаю.Ответы:
Как насчет того, чтобы сделать небольшую математику с вашим столбцом идентификаторов для динамического создания группы?
Это даст вам группы по 10 на основе идентификатора записи. Я использовал вашу таблицу животных выше, чтобы сгенерировать данные ниже.
Образец данных
Вывод запроса
источник
В SQL, как правило, это будет:
ОТЛИЧИТЕЛЬНЫЙ отборВернуться к главной таблице на клавишах DISTINCTЭто не агрегат, поэтому GROUP BY не требуется
Редактировать:
На самом деле, NTILE достаточно, чтобы создать «n блоков на набор различных значений»
источник
Я до сих пор не вижу полных решений (которые действительно работают в MySQL), так что это решение, которое я, вероятно, буду использовать:
Я все еще надеюсь, что кто-то сможет победить этот ответ; Я не хочу принимать мой собственный ответ. Я говорил это раньше, но с самого начала я знал, как это сделать # 2; # 1 это то, что беспокоило меня. Если вы можете ответить на # 1, тогда вы на самом деле ответите и на другой вопрос , но, возможно, можно будет ответить на этот вопрос иным способом, чтобы обойти # 1.
источник
источник