Selecione onde a contagem de um campo é maior que um


100

Eu quero fazer algo assim:

SELECT * 
  FROM db.table 
 WHERE COUNT(someField) > 1

Como posso fazer isso no MySql?

Respostas:


146

Use a cláusula HAVING, not WHERE, para comparação de resultados agregados.

Tomando a consulta pelo valor de face:

SELECT * 
  FROM db.table 
HAVING COUNT(someField) > 1

Idealmente, deve haver um GROUP BYdefinido para a avaliação adequada na HAVINGcláusula, mas o MySQL não permite colunas ocultas do GROUP BY ...

Isso está em preparação para uma restrição exclusiva someField? Parece que deveria ser ...


11
Precisa de uma GROUP BYcerteza (a menos que seja alguma coisa não padrão do MySQL)?
Martin Smith,

@Martin Smith: Aceitou a consulta pelo valor de face; abordou o problema de GROUP BY (incluindo o recurso de colunas ocultas).
Pôneis OMG de

"Parece que deveria ser ..." Por quê? Estou precisando de informações sobre isso :)
Dave

Portanto, isso retornará a tabela inteira se ela contiver mais de 2 someFieldvalores não nulos ou um conjunto de resultados vazio se não contiver .
Martin Smith,

@Dave: Se você estivesse em uma posição em que tivesse que verificar e corrigir dados incorretos periodicamente, não gostaria de impedir que a situação acontecesse? MySQL implementa uma restrição única como um índice - para obter mais informações, consulte a documentação CREATE INDEX
Pôneis OMG

18
SELECT username, numb from(
Select username, count(username) as numb from customers GROUP BY username ) as my_table
WHERE numb > 3

3
a única ressalva aqui (pelo menos em 5.1.46-community MySQL Community Server (GPL)) é que "Cada tabela derivada deve ter seu próprio alias", que fará com que seu sql se pareça com: SELECT username, numb from (Select username, contagem (nome de usuário) como numb de clientes GROUP BY nome de usuário) como minha_tabela WHERE numb> 3
D_K

14

Você também pode fazer isso com uma autojunção:

SELECT t1.* FROM db.table t1
JOIN db.table t2 ON t1.someField = t2.someField AND t1.pk != t2.pk

11

Aqui está:

SELECT Field1, COUNT(Field1)
  FROM Table1 
 GROUP BY Field1
HAVING COUNT(Field1) > 1
ORDER BY Field1 desc

4

Mão única

SELECT t1.* 
FROM db.table t1
WHERE exists 
      (SELECT *
      FROM db.table t2 
      where t1.pk != t2.pk 
      and t1.someField = t2.someField)

1

Como OMG Ponies afirmou, a cláusula de ter é o que você está depois. No entanto, se você esperava obter linhas discretas em vez de um resumo (o "ter" cria um resumo) - isso não pode ser feito em uma única instrução. Você deve usar duas instruções nesse caso.


1
Não é totalmente verdade - use o GROUP BY para manipular o que o HAVING está usando.
Pôneis OMG de

1

Dou um exemplo no Group By entre duas tabelas no Sql:

Select cn.name,ct.name,count(ct.id) totalcity from city ct left join country cn on ct.countryid = cn.id Group By cn.name,ct.name Having totalcity > 2



1

Para mim, não ter um grupo por apenas retornou resultado vazio. Então eu acho que ter um grupo para a declaração de ter é muito importante


-2

Também deve ser mencionado que o "pk" deve ser um campo chave. A auto-adesão

SELECT t1.* FROM db.table t1
JOIN db.table t2 ON t1.someField = t2.someField AND t1.pk != t2.pk 

por Bill Karwin dar-lhe todos os registros que são duplicados que é o que eu queria. Como alguns têm mais de dois, você pode obter o mesmo registro mais de uma vez. Eu escrevi tudo em outra tabela com os mesmos campos para me livrar dos mesmos registros por supressão de campos-chave. eu tentei

SELECT * FROM db.table HAVING COUNT(someField) > 1

acima primeiro. Os dados retornados fornecem apenas uma das duplicatas, menos da metade do que isso fornece, mas a contagem é boa se isso for tudo o que você deseja.


3
Isso não é realmente uma resposta.
anon582847382
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.