Reputation: 141
I have table with a enum column with possible values of 'relative' and 'absolute'. There maybe duplicate rows with the difference being that column.
So normally I would select a row with the 'absolute' value but I need and if caluse to check if there is a 'duplicate' row where the column is 'relative' and then select that row instead (if there is a reletive row, there will always be absolute row too)
pseudo code:
select *
from table
where non_unique_col = 123
and IF (has result row with 'relative'
then return that row
else return 'absolute' row)
Upvotes: 3
Views: 171
Reputation: 51990
If the row are identical apart from the relative or absolute part and if you require only on row for each non_unique_column value, why not simply using:
select non_unique_col, max(rel_or_abs), extra_data from tbl
group by non_unique_col;
See http://sqlfiddle.com/#!2/b97fc0/2
Upvotes: 0
Reputation: 28196
SELECT *
FROM table1
INNER JOIN (
SELECT non_unique_col nuc,
MAX(absolute_relative_col) rec
FROM table1
GROUP BY non_unique_col
) AS t ON nuc=non_unique_col AND rec=absolute_relative_col
-- (@Zessx: second condition is still part of the INNER JOIN ...)
EDIT:
But I like the idea with COALESCE (see comment of Strawberry, above!) much better:
SELECT * FROM table1 WHERE id IN (
SELECT COALESCE(b.id,a.id) FROM tablel a
LEFT JOIN tbl b ON b.non_unique_col=a.non_unique_col
AND b.absolute_relative_col='relative'
)
Upvotes: 0
Reputation: 18584
You could try this:
SELECT *
FROM `table`
WHERE `non_unique_col` = 123
ORDER BY `absolute_relative_col` DESC
LIMIT 1
This way, if there is exactly one result, no problem the, if there are more, you get the 'relative' one.
EDIT:
As per @Travesty3 suggestion, I'd like to underline that this query is made on the assumption that (non_unique_col + absolute_relative_col)
makes a unique_col
, which is based on OP statements that
There maybe duplicate rows with the difference being that column
and
if there is a relative row, there will always be absolute row too
EDIT 2:
A more generic solution could be the following:
SELECT *
FROM `table` as t1
JOIN (
SELECT non_unique_col, absolute_relative_col
FROM `table`
WHERE `absolute_relative_col` = 'relative'
) as t2 USING (non_unique_col)
WHERE t2.absolute_relative_col = 'relative' OR (
t2.absolute_relative_col IS NULL
AND t1.absolute_relative_col = 'absolute'
)
Upvotes: 2
Reputation: 20737
The following (untested) query should return what you want, but as with most queries that use subqueries, I don't think it is very efficient.
SELECT *
FROM `table`
WHERE `non_unique_col`=123
AND (
(`relativity` = 'relative')
OR (`relativity` = 'absolute'
AND NOT EXISTS (
SELECT 1
FROM `table`
WHERE `non_unique_col`=123
AND `relativity`='relative'
)
)
);
See this documentation.
Edit: If you would want to create a list of this (e.g. without the id), then you would write something like this:
SELECT *
FROM `table` as a
WHERE (`relativity` = 'relative')
OR (
`relativity` = 'absolute'
AND NOT EXISTS (
SELECT 1
FROM `table` as b
WHERE a.`non_unique_col`=b.`non_unique_col`
AND `relativity`='relative'
)
);
Upvotes: 0