Search code examples
sqldbvisualizer

Removing Duplicate Rows in SQL


I have a query that returns a list of devices that have multiple "moved" dates. I only want the oldest date entry. I used the MIN function to give me the oldest date, but I'm still getting multiple entries (I am, however, getting less than before). I tried to get a more precise JOIN, but I couldn't narrow the fields down any more.

If you'll look at the screenshot, the first three rows have the same "wonum" but three different "Moved Dates." I am thinking that if I can somehow take the oldest "Moved Date" out of those three and remove the other rows, that would give me the result I'm looking for. However, I'm not skilled enough to do that (I've only been working in SQL for a few months now). Would that work, or is there a better way to narrow down my results? I'm wondering if I need to perform some kind of sub-query to get what I need.

I've looked around but can't find anything that allows me to remove a row of data the way I'm looking to. Nor can I seem to find a reason my MIN function isn't paring down the data anymore than it is. Below is the code I'm currently using. Thanks for any help that can be given.

SELECT wo.wonum, wo.location, wo.statusdate, wo.status, l.subcontractor,
    wo.description, MIN(ast.datemoved) AS 'Moved Date'
FROM workorder wo
        JOIN locations l ON wo.location = l.location
        JOIN asset a ON wo.location = a.location 
          -- AND wo.assetnum = a.assetnum
        JOIN assettrans ast ON a.assetnum = ast.assetnum
          -- AND a.assetid = ast.assetid
WHERE wo.description LIKE '%deteriorating%'
        AND wo.status != 'close'
GROUP BY wo.wonum, wo.location, wo.statusdate, 
  wo.status, l.subcontractor, wo.description
ORDER BY wo.wonum;

DBV SQL Query Result

Update: Table Data


Solution

  • You need to do the grouping in your join statement inside a subquery(not tested, but you'll get the idea):

    Replace

    JOIN assettrans ast ON a.assetnum = ast.assetnum
    

    With

    inner join
    (
        select ast.assetnum,MIN(ast.datemoved) AS 'Moved Date' 
        from assettrans ast  
        group by ast.assetnum
    ) grouped
    on a.assetnum = grouped.assetnum
    

    So the full query looks like:

    SELECT wo.wonum, wo.location, wo.statusdate, wo.status, l.subcontractor,
        wo.description, grouped.MovedDate
    FROM workorder wo
            JOIN locations l ON wo.location = l.location
            JOIN asset a ON wo.location = a.location 
            INNER JOIN
            (
               select ast.assetnum,MIN(ast.datemoved) AS MovedDate 
               from assettrans ast  
               group by ast.assetnum
            ) grouped
            on a.assetnum = grouped.assetnum
        WHERE wo.description LIKE '%deteriorating%'
                AND wo.status != 'close'
        ORDER BY wo.wonum;