tags:

views:

76

answers:

4

Having this table:

Row    Pos      Outdata    Mismatch          Other
1        10       S           0               A
2        10       S           5               A
3        10       R           0               B
4        10       R           7               B
5        20       24          0               A
6        20       24          5               B
6        20       32          10              C

How can I select all rows where Pos=10 having unique Outdata. If more than one row exists, I would like to have the row where the field Mismatch is smallest. Ie I would like to get rows 1 and 3, not 2 and 4.

In that select I would also like to do the same for all Pos=20, so the total result should be rows 1,3,5,6

(And I want to then access the "Other" field, so I cant only SELECT DISTINCT on Pos and OutData and Mismatch).

Is there a query to do this in MySQL?

+1  A: 

Try this:

Select * From Table ot
Where pos = 10 
   And MisMatch = 
       (Select Min(MisMatch) From Table
        Where pos = 10
           And Outdata = ot.OutData)
Charles Bretana
Hmmm... is there some way to remove the dependency from the subquery? Dependent subqueries have to be run once for each row in the outer result set, which would be once for each row in the table in this case.
R. Bemrose
Not that I'm aware of, you want to restrict the query to only those rows where the mismatch is the lowest Mismatch for that set of rows with the same OutData. That implies a correlation between the two constructs (the mismatch value, and the set of rows with the same OutData value). Whether you use a subquery or a join of some kind, that correlation must be processed to generate the right output rows
Charles Bretana
Thanks all, will try out and think through all the answers!
Petter Magnusson
Did not try this, looks a bit too simple but could perhaps work!?
Petter Magnusson
+1  A: 

Rationale is to create a table with all values of Pos, OutData and the lowest Mismatch and use the combination of these fields as a unique key into your actual table.

SELECT    t1.*
FROM      MyTable t1
          INNER JOIN (
            SELECT    Pos, OutData, Mismatch = MIN(Mismatch)
            FROM      MyTable
            GROUP BY  Pos, OutData
          ) t2 ON t2.Pos = t1.Pos
                  AND t2.OutData = t1.OutData
                  AND t2.Mismatch = t1.Mismatch
Lieven
Thanks all, will try out and think through all the answers!
Petter Magnusson
This worked fine with some additional WHERE for t2 and AND with the same conditions for t1 after ON!
Petter Magnusson
A: 

This should work for you:

 SELECT * 
 FROM table T1 
 GROUP BY Pos, Outdata 
 HAVING Mismatch = (
     SELECT MIN(Mismatch)
     FROM table T2
     WHERE Pos = T1.Pos AND
     Outdata = T1.Outdata
 )
RaYell
Thanks all, will try out and think through all the answers!
Petter Magnusson
HAVING after GROUP BY does not work.
Petter Magnusson
It does work. It doesn't work if you don't have `GROUP BY`.
RaYell
Hi RaYell, sorry for the unclear comment. It WORKS, but does not solve this problem.
Petter Magnusson
+1  A: 

Here I am assuming that (Pos, OutData, Mismatch) is not unique, but that (Row, Pos, OutData, Mismatch) is unique:

SELECT T3.*
FROM Codes T3
JOIN (
    SELECT MIN(Row) AS Row
    FROM (
        SELECT Pos, OutData, Min(Mismatch) AS Mismatch
        FROM Codes
        GROUP BY Pos, OutData
    ) T1
    JOIN Codes T2
    ON T1.Pos = T2.Pos AND T2.OutData = T2.Outdata AND T1.Mismatch = T2.Mismatch
    GROUP BY T2.Pos, T2.OutData, T2.Mismatch
) T4
ON T3.Row = T4.Row

Result:

1, 10, 'S', 0, 'A'
3, 10, 'R', 0, 'B'
5, 20, '24', 0, 'A'
7, 20, '32', 10, 'C'

Note that I have also corrected the second row 6 to become row 7, as I believe that this was a mistake in the question.

Mark Byers
Thanks! Will check on this and get back!
Petter Magnusson
Never tried this, but it looks good. Accepted another solution, but thanks for the effort!
Petter Magnusson
@Petter: the solution you have accepted assumes that (Pos, OutData, Mismatch) **is** unique. If that is always true, then that solution is best - given two solutions that both work, pick the simpler solution. However, if that assumption is not always true, the solution you've accepted will fail (it will return multiple rows for the same Pos, OutData). Since you haven't specified your assumptions, I couldn't know which assumption to make so I played it safe: making a slightly more complex solution that will always work.
Mark Byers
Thanks Mark, I realised that problem, and think I can live with that limitation for now. It may well be that I will have to look into using your technique later. For now I go for the simpler one as this is only part of a more complex sql task that I have to solve. (Tried asking that more complex question earlier but no-one understood the question, it was too complex so I broke it into parts like this, let me know if you want a real tricky SQL problem....;-).
Petter Magnusson