Eu tenho uma tabela que contém várias chaves em outras tabelas (onde cada chave é composta de várias colunas). Gostaria de poder agrupar linhas que tenham uma chave igual, mas não quero agrupar todas elas. Não é simples GROUP BY
na chave, mas quero poder fazer grupos de dizer 10. Portanto, se uma chave específica aparecesse 50 vezes, obteria 5 resultados ao fazer esse agrupamento (5 grupos de 10). Também quero que esse agrupamento ocorra aleatoriamente dentro da chave.
Eu não sabia a maneira direta de fazer isso, e o método indireto que eu criei não está funcionando como eu acho que deveria. A solução da rotatória que eu criei foi criar uma nova coluna para cada chave que seria um número inteiro, de modo que o valor i
represente a ith
ocorrência dessa chave (mas em ordem aleatória). Eu poderia então fazer a divisão inteira para que cada n (digamos 10) linhas na chave tivesse o mesmo valor, e eu poderia fazer GROUP BY
isso nesse valor.
Existe uma maneira mais direta de realizar o que acabei de descrever? É bastante estranho e tive problemas ao criar a nova coluna de índice (como descrevi nesta pergunta ).
EDIT: Antes de mais nada, note que isto é para o MySQL. Vou adicionar um exemplo caso meu objetivo não esteja claro. Os documentos do MySQL mostram um método para chegar quase lá :
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;
Isso cria uma tabela que, embora não seja o que eu quero, se aproxima:
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
Gostaria essencialmente de GROUP BY
identificar, exceto que eu gostaria que os registros mammal
tivessem um "grupo" para os IDs 1-10, outro "grupo" para os IDs 11-20, etc. No entanto, eu faria isso com uma tabela existente, e eu não gostaria necessariamente que "cachorro" aparecesse com o ID 1. Gostaria que essa ordem inicial fosse aleatória, mas determinística a partir de então.
I would want that initial ordering to be random, but then deterministic from then out.
<- diz o que? Acho que não importa o que você faça, você terá que colocar os registros em uma segunda tabela de algum tipo. Com que precisão essa lógica de negócios funciona? Como é que não há nada a exigir (por exemplo) cachorro para vir em primeiro lugar. E o que você quer dizer comI would want the records from *mammal* to have one "group" for IDs 1-10, and another for IDs 11-20
... você pode ilustrar isso com outra tabela, com foco em mamíferos, na descrição da pergunta acima?numMammal
. Realmente não me importo com o que o IDdog
recebe, mas não quero que ele dependa do pedido de inserção original.GROUP BY
. Talvez eu queira emparelhar grupos de 10 para encontrar a correlação entre a média. Preciso dessa ordem aleatória, porque se a ordem de inserção original fosse classificada por peso, isso me daria resultados errados. Espero estar fazendo sentido.Respostas:
Que tal fazer um pouco de matemática com sua coluna de ID para gerar dinamicamente o grupo?
Isso daria a você grupos de 10 com base no ID do registro. Usei a tabela de animais acima para gerar os dados abaixo.
Dados de amostra
Saída de consulta
fonte
No SQL, geralmente isso seria:
uma subseleção DISTINCTVOLTAR à tabela principal com as teclas DISTINCTComo não é um agregado, GROUP BY não é necessário
Editar:
Na verdade, NTILE é suficiente por si só para criar "n buckets por conjunto de valores distintos"
fonte
Ainda não estou vendo nenhuma solução completa (que realmente funcione no MySQL), então esta é a solução que provavelmente vou usar:
Ainda espero que alguém consiga vencer essa resposta; Não quero ter que aceitar minha própria resposta. Eu já disse isso antes, mas sabia desde o início como fazer o segundo; O número 1 está me incomodando. Se você puder responder à pergunta nº 1, também responderá a outra pergunta , mas talvez seja possível responder a essa pergunta de alguma outra maneira, para contornar a pergunta nº 1.
fonte
fonte