How to get the first result of duplicate lines?

Asked

Viewed 1,494 times

3

Situation:

In a table there is a list of items with their respective values invoiced in invoice. This table has a single field that varies according to the insertion of the data, can repeat all other columns and does not have a PK. An example would be:

fk_nota_fiscal | fk_produto | valor | campo2 | campoXXX
244060         | 0010101    | 100,00| X      | A       
244060         | 0010101    | 100,00| X      | B     
244060         | 0010101    | 100,00| X      | C     

Desired:

I need to get only the first result regardless of the variation of the column campoXXX.

Problem encountered:

Using the functions ROW_NUMBER() and OVER(), I grouped the results into one CTE and I was able to select only the first result, but the performance is absurdly slow and unviable for a considerable amount of records.

ROW_NUMBER() OVER(PARTITION BY fk_nota_fiscal,fk_produto ORDER BY fk_nota_fiscal,fk_produto) AS ROWID

SELECT * FROM FROM CTE_vwItensRefaturar WHERE ROWID = 1
  • you own an Intel for fk_nota_fiscal and fk_produto?

  • No, Tobymosque. I’m seeing about it and if it somehow optimizes performance.

  • See the possibility to create a pk or Indice clustered, envovendo fk_nota_fiscal, fk_product and other field (campoXXX? ). I don’t see how you get a significant gain by replacing your current strategy with one of the ones suggested in the answers (including, except for the suggestion given by @Onosendai, you get a loss instead of gain).

2 answers

2


You can use a sub select with top 1 to do this along with the group by do select,

select fk_nota_fiscal,  fk_produto, valor,  campo2,
(select top 1 campoXXX from @teste t2 
        where t2.fk_nota_fiscal = t1.fk_nota_fiscal and t2.fk_produto = t1.fk_produto) 
from @teste t1
group by fk_nota_fiscal,    fk_produto, valor,  campo2

Or use the function FIRST_VALUE sql server, but you still have to use a sub select.

Select * from
    (
        SELECT   fk_nota_fiscal,
                 fk_produto,
                 valor,
                 campo2,
                 FIRST_VALUE(campoXXX) OVER (ORDER BY fk_nota_fiscal ASC) AS campoXXXX   
        FROM     @teste
    ) d
    GROUP BY fk_nota_fiscal,
             fk_produto,
             valor,
             campo2,
             campoXXXX

A solution, I don’t know if feasible for your structure, would be the creation of a table (mirror) of your table, as this you could perform your query to make the desired data Inserts and a TRIGGER in your original table to update this table when there is change, with this you could make the select right in your table(mirror).

  • Goku, with FIRST_VALUE, it does not need a sub-quota, actually replace the ORDER BY for PARTITION BY, but this command is only available on SqlServer 2012 and unfortunately there are many people trapped in the SqlServer 2008 (and earlier), but even so, it is an unrelenting alternative, but I don’t think it will perform better than the ROW_NUMBER (due to the optimizations made by Engine of SqlServer).

  • @Tobymosque, the syntax of FIRST_VALUE requires having an ORDER BY (The Function 'FIRST_VALUE' must have an OVER clause with ORDER BY.), well did not know which version he was using and also did not think of other people who user lower versions.

1

Have you tried this? (This syntax may vary depending on the database, this is for sql server)

SELECT TOP 1 fk_nota_fiscal, fk_produto, valor, campo2, campoXXX
FROM table_name;

Or distinct?

SELECT DISTINCT fk_nota_fiscal, fk_produto, valor, campo2
FROM table_name;
  • DISTINCT works only if all columns are identical. O TOP will only return to N reported occurrence of the entire table, I need to bring the first record of all.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.