registros internos sobre registros externos

I am stuck with this problem. I have duplicates in my query coming from that some of the records are in-house and outside simultaneously. I prefer in-house over outside but some of the outside are preferable when there is no entrance from in-house.

Select id, date, location from prod

id date        location
----------
2  01/01/2012  in-house
2  05/01/2012  outside <- in this situation i want to keep just in-house

id date        location
----------
4  01/01/2012  in-house
5  03/01/2012  outside <- in this situation i want to keep both since there is no db entry for id=5 therefor i have just info from outside

¿Alguien podría ayudar?

preguntado el 22 de mayo de 12 a las 17:05

Can you edit your question, perhaps? I don't think it's clear what problem you're trying to solve. -

Can I try to para-phrase? You want one record returned per id? And that should be chosen with location = outside teniendo precedencia sobre location = in-house. And, I presume, if there are still multiple records for that id, choose the one with the highest date ¿valor? [Also, what brand of SQL are you using? MySQL, SQL Server, Oracle? And what release/version?] -

Hi, i have access to SQL Server. If there are multiple rec for id i would like max date value and always choosing in-house over outside. Sorry i am aware it isnt clearest explanation but you are grasping it correctly. -

1 Respuestas

One way to do this is to do a full outer join from your table to itself and then use coalesce.

 Select 
    COALESCE(Inside.Id, outside.id) Id,
    COALESCE(Inside.date, outside.date) Date,
    COALESCE(Inside.location, outside.location) Location
From 
    prod Inside
    FULL OUTER JOIN prod Outside
    ON Inside.id = Outside.iD
    and Inside.location <> Outside.Location
Where
    (Inside.Location = 'in-house'
    or 
    Inside.Location is null)
    and 
    (outside.Location = 'outside'
     or
     outside.Location is null)

DEMO

Notas

If your fields can be nullable you may want to use a Case statement instead of coalesce and use the ID field to determine which table to use. Using the date as an example

CASE WHEN Inside.Id is not null THEN Inside.date ELSE outside.date END date

As Dems noted this also assumes that {id, location} es único.

ACTUALIZACIÓN

Since you're using SQL Server and {ID, Location} isn't unique and you want the max date value and always choosing in-house over outside then you can use ROW_NUMBER/WHERE RowNumber = 1 effectively here, by ordering First on location and then by date.

WITH cte 
     AS (SELECT Row_number() OVER ( partition BY ID 
               ORDER BY CASE LOCATION WHEN  'in-house' THEN 0  
                                      WHEN  'outside' THEN 1 END, 
                        DATE DESC) rn, 
                ID, 
                Date, 
                Location 
         FROM   prod) 
SELECT ID, 
       Date, 
       Location 
FROM   cte 
WHERE  rn = 1 

Demo

Note We didn't have to use a case statement but I wanted the mapping to be explicit.

contestado el 22 de mayo de 12 a las 18:05

Conrad Frix - thank you very much - applied it and it works - now i need to understand the logic but you were great. thx - grozny

@Gronzy glad to help. BTW if you add more test cases, remove the where clause and add rn to the Select clause it might make more sense. Mira aquí - Conrado Frix

@ConradFrix this is very neat - now i wish it could be as easy for me as you just produced it but maybe with a time. Anyway thanks again. - grozny

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.