A cláusula DISTINCT elimina linhas duplicadas dos resultados recuperados pela SELECT. Ela mantem uma linha para cada grupo de duplicados. Essa linha é imprevisivel, a menos que seja usado o comando ORDER BY, para garantir que a linha desejada apareça primeiro.

SELECT DISTINCT department FROM employees;

DISTINCT tambem pode ser usado em varias colunas de uma so vez; nesse caso, avaliará as duplicatas com base na combinação de valores dessas colunas. O comportamento do DISTINCT pode ser simulado pela clausula GROUP BY.

SELECT department FROM employees GROUP BY department;

Vamos imaginar que temos duas tabelas separadas: users e logins. Usaremos DISTINCT ON para encontrar as informaç&optilde;es sobre o login mais recente de cada usuario.

    
      
          CREATE TABLE users (
          	username text not null,
          	email text not null,
            CONSTRAINT users_pk PRIMARY KEY (username)
          );
      
    
  
    
      
      INSERT INTO users (username, email) VALUES
         ('Zosia', 'zosia@example.com'),
         ('Jasiu', 'jasiu@example.com'),
         ('Krysia', 'krysia@example.com');

      CREATE TABLE logins (
          username text not null,
        	browser text not null,
        	logged_at timestamp not null,
          CONSTRAINT logins_pk PRIMARY KEY (username, logged_at),
          CONSTRAINT logins_fk_username FOREIGN KEY (username) REFERENCES users(username)
      );

      INSERT INTO logins (username, browser, logged_at) VALUES
          ('Zosia', 'Safari', '2000-01-01 11:10:01'),
          ('Zosia', 'Chrome', '2000-01-02 11:10:01'),
          ('Zosia', 'Safari', '2000-01-03 11:10:01'),
          ('Jasiu', 'Firefox', '2000-02-01 11:10:01'),
          ('Jasiu', 'Chrome', '2000-02-02 11:10:01'),
          ('Jasiu', 'Chrome', '2000-02-03 11:10:01'),
          ('Krysia', 'Opera', '2000-03-01 11:10:01'),
          ('Krysia', 'Safari', '2000-03-02 11:10:01'),
          ('Krysia', 'Opera', '2000-03-03 11:10:01');
        
    
  

Aqui esta a nossa consulta que une essas duas tabelas e imprime o login mais recente. O DISTINCT ON requer que sua expressao (isto é, u.username em nosso exemplo) corresponda à primeira expressão usada na clausula ORDER BY.

    
      
        SELECT DISTINCT ON (u.username) u.username, u.email, l.browser, l.logged_at
        FROM users u
        JOIN logins l ON l.username = u.username
        ORDER BY u.username, logged_at DESC
        
    
  

Aqui esta o resultado:

    
      
         username |       email        | browser |      logged_at
        ----------|--------------------|---------|----------------------
         Jasiu    | jasiu@example.com  | Chrome  | 2000-02-03 11:10:01
         Krysia   | krysia@example.com | Opera   | 2000-03-03 11:10:01
         Zosia    | zosia@example.com  | Safari  | 2000-01-03 11:10:01
        
    
  

Vamos considerar outro exemplo: encontrar o empregado com o maior salario em cada departamento. A solução basica poderia ser a seguinte:

    
      
        SELECT  * 
        FROM employees 
        WHERE(department, salary) IN (
            SELECT department, MAX(salary) FROM employees
            GROUP BY department
        )
        ORDER BY department;
        
    
  

Mas podemos usar tambem o PARTITION para conseguir o mesmo efeito.

    
      
        WITH ranked_employees AS (
          SELECT ROW_NUMBER() OVER (
            PARTITION BY department ORDER BY salary DESC
          ) AS rn, * FROM employees
        )
        SELECT * FROM ranked_employees
        WHERE rn = 1
        ORDER BY department;
        
    
  

A clausula DISTINCT ON do PostgreSQL, no entanto, simplifica muito essa consulta:

    
      
        SELECT DISTINCT ON (department) * FROM employees
        ORDER BY department, salary DESC;
        
    
  

Espero que esse post tenha ajudado e muito obrigado!

Instagram