0

I have the following table and data:

DECLARE @Temp TABLE (id int, city varchar(10), ref varchar(10))

INSERT INTO @Temp (id, city, ref)
SELECT 1, 'London', 'GBP' UNION ALL
SELECT 2, 'London', 'EUR' 

SELECT  *
FROM    @Temp
WHERE ((city = 'London' AND ref = 'GBP') OR (city = 'London' AND ref <> 'GBP'))

This returns:

1 London GBP
2 London EUR

What I would like to do is to check for where city = 'London' AND ref = 'GBP' first, if there is no row qualifying this then check if the city is London and ref can be anything, tried using case when but did not quite work.

In this scenario I should only get the row #1.

Thanks

7 Answers 7

1

Just return the rows not containing GBP when there are no GPB rows, using NOT EXISTS:

SELECT  *
FROM    @Temp
WHERE (city = 'London' AND ref = 'GBP') OR (city = 'London' AND NOT EXISTS (SELECT  *
            FROM    @Temp
            WHERE city = 'London' AND ref = 'GBP'))
Sign up to request clarification or add additional context in comments.

Comments

1

If you are dealing with single record, then next should work:

SELECT  TOP 1 *
FROM    @Temp
WHERE city = 'London'
ORDER BY CASE WHEN ref = 'GBP' THEN 0 ELSE 1 END

1 Comment

TOP 1 by default doesn't return ties. OP problem description is not very clear, I assumed that he always wants to return only single row.
1
SELECT *
FROM @Temp
WHERE city = 'London' AND ref = 'GBP'
UNION
SELECT *
FROM @Temp
WHERE NOT EXISTS (
    SELECT * 
    FROM @Temp 
    WHERE city = 'London' AND ref = 'GBP'
) AND city = 'London'

SELECT after UNION is conditional where.

Comments

1

You can use CASE WHEN:

SELECT  *
FROM @Temp
WHERE 
  CASE
   WHEN city = 'London' AND ref = 'GBP' THEN 1
   WHEN city = 'London' AND ref <> 'GBP' AND NOT EXISTS(SELECT 1 FROM @Temp
                                                        WHERE city = 'London' 
                                                        AND ref = 'GBP') THEN 1
   ELSE 0
END = 1

LiveDemo

Comments

0
select city, max(ref)
from @Temp
group by city

Alternatively

select city, ref
from @Temp t1
where t1.ref = 'GBP'
   or not exists (select 1 from @Temp t2
                  where t2.city = t1.city
                    and t2.ref = 'GBP')

Comments

0

I think you can deal with ordering in the case like this

SELECT TOP 1 *
FROM @Temp t 
    CROSS APPLY -- The ordering logic write here
    (
        SELECT
            CASE 
                WHEN (city = 'London' AND ref = 'GBP') THEN 1
                WHEN (city = 'London' AND ref <> 'GBP') THEN 2
                -- Not match at all
            END AS Value
    ) orders
WHERE orders.Value IS NOT NULL
ORDER BY 
    CASE WHEN orders.Value IS NULL THEN 1 ELSE 0 END, 
    orders.Value

Comments

0

You can try with NOT EXISTS something like:

SELECT  *
FROM    @Temp
WHERE ((city = 'London' AND ref = 'GBP') OR (city = 'London' AND ref <> 'GBP'
      AND NOT EXISTS (SELECT *
                      FROM  @Temp
                      WHERE city = 'London' AND ref = 'GBP')))

2 Comments

Your second solution doesn't work: ordering by id doesn't guarantee that the GBP will be the first row (in this case yes, but this certainly won't be the case everytime).
Same with ref, what if some other currency exists named, say, USD ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.