views:

54

answers:

4

Hi All, I have a quick question. How do I select the two values I need in one query? Currently I'm doing this, which works fine, but it's obviously running two queries when one should do the trick. I tried MAX(columnA) and GROUP BY ColumnB, but that returns multiple row. I only want one row returned.

DECLARE @biID  bigint  
, @dtThreshold      DateTime 

  SELECT @biID = MAX(biID)
FROM tbPricingCalculationCount WITH (NOLOCK)

  SELECT @dtThreshold = dtDateTime
FROM tbPricingCalculationCount WITH (NOLOCK)
WHERE biID = @biID

I would like both those variables to be set correctly in one query. How can I do that?

Thanks, ~ck

+8  A: 

can you not just do this?

SELECT TOP 1 @biID = biID, @dtThreshold = dtDateTime 
  FROM tbPricingCalculationCount WITH (NOLOCK) 
ORDER BY biID DESC;
oedo
+1  A: 

How about

SELECT TOP 1 @biID = biID, @dtThreshold = dtDateTime
FROM tbPricingCalculationCount (NOLOCK)
ORDER BY biID desc
Chris Lively
+1  A: 

This returns dtDateTime for the row with the largest biID:

SELECT t1.dtDateTime
FROM tbPricingCalculationCount t1
LEFT JOIN tbPricingCalculationCount t2
ON t2.biID > t1.biID
WHERE t2.biID IS NULL

If more than one row shares the same "largest" biID, then you need to limit the results to one using TOP:

SELECT TOP 1 t1.dtDateTime
FROM tbPricingCalculationCount t1
LEFT JOIN tbPricingCalculationCount t2
ON t2.biID > t1.biID
WHERE t2.biID IS NULL
Marcus Adams
are you sure that even works? you can't join on a `<`, only an `=`, or have i missed something? also, what is the NULL WHERE clause about?
oedo
You can join on any criteria. Also, the NULL WHERE criteria says you want the row where there isn't a larger biID.
Marcus Adams
well i learn a new thing every day then :)
oedo
Wow. That's a roundabout way of doing it.
Chris Lively
@Chris, this is really efficient, assuming an index on the biID column.
Marcus Adams
@marcus, i'm interested : is it any more efficient than a simple order by desc?
oedo
@oedo, probably not. In this case, the simple `ORDER BY` with `TOP` is probably the best solution. It is often better than a subquery, though.
Marcus Adams
+1  A: 

How about:

DECLARE
  @biID bigint,
  @dtThreshold DateTime 

SELECT
  @dtThreshold = A.dtDateTime,
  @biID = B.biID
FROM tbPricingCalculationCount A
  INNER JOIN (SELECT MAX(biID) biID
              FROM tbPricingCalculationCount) B
    ON A.biID = B.biID

If you're not using the biID elsewhere, you can even trim it to:

DECLARE
  @dtThreshold DateTime 

SELECT
  @dtThreshold = A.dtDateTime
FROM tbPricingCalculationCount A
  INNER JOIN (SELECT MAX(biID) biID
              FROM tbPricingCalculationCount) B
    ON A.biID = B.biID
foriamstu