views:

77

answers:

4

Yesterday Thomas helped me a lot by providing exactly the query I wanted. And now I need a variant of it, and hopes someone can help me out.

I want it to output only one row, namely a max value - but it has to build on the algorithm in the following query:

WITH Calendar AS (SELECT     CAST(@StartDate AS datetime) AS Date
                                          UNION ALL
                                          SELECT     DATEADD(d, 1, Date) AS Expr1
                                          FROM         Calendar AS Calendar_1
                                          WHERE     (DATEADD(d, 1, Date) < @EndDate))
    SELECT     C.Date, C2.Country, COALESCE (SUM(R.[Amount of people per day needed]), 0) AS [Allocated testers]
     FROM         Calendar AS C CROSS JOIN
                            Country AS C2 LEFT OUTER JOIN
                            Requests AS R ON C.Date BETWEEN R.[Start date] AND R.[End date] AND R.CountryID = C2.CountryID
     WHERE     (C2.Country = @Country)
     GROUP BY C.Date, C2.Country OPTION (MAXRECURSION 0)

The output from above will be like:

Date            Country         Allocated testers
06/01/2010      Chile             3
06/02/2010      Chile             4
06/03/2010      Chile             0
06/04/2010      Chile             0
06/05/2010      Chile            19

but what I need right now is

Allocated testers
           19

that is - only one column - one row - the max value itself... (for the (via parameters (that already exists)) selected period of dates and country)

+3  A: 

use order and limit

ORDER BY 'people needed DESC' LIMIT 1 

EDITED

as LIMIT is not exist in sql

use ORDER BY and TOP

select TOP 1 .... ORDER BY 'people needed' DESC
Salil
LIMIT does not exists in SQL Server. I believe you are talking about MySQL.
Lieven
`SELECT TOP 1 ...` would be the quivalent for SQL server .. (*coupled with a `ORDER BY [people needed] DESC` at the end*
Gaby
@Gaby:- Thanx i edit my answer hope that works.....
Salil
@Salil, a minor typo .. pute the `desc` outside the quotes..
Gaby
oohhhhh thanx again @Gaby
Salil
I guess you mean I should put it into context as MaasSql suggested? Well, for some reason I can´t get it rolling... :-(
Jack Johnstone
+2  A: 
WITH  Calendar
        AS (
             SELECT
              CAST(@StartDate AS datetime) AS Date
             UNION ALL
             SELECT
              DATEADD(d, 1, Date) AS Expr1
             FROM
              Calendar AS Calendar_1
             WHERE
              ( DATEADD(d, 1, Date) < @EndDate )
           )
SELECT TOP 1 *
FROM 
(           
  SELECT
    C.Date
   ,C2.Country
   ,COALESCE(SUM(R.[Amount of people per day needed]), 0) AS [Allocated testers]
  FROM
    Calendar AS C
    CROSS JOIN Country AS C2
    LEFT OUTER JOIN Requests AS R
      ON C.Date BETWEEN R.[Start date] AND R.[End date]
         AND R.CountryID = C2.CountryID
  WHERE
    ( C2.Country = @Country )
  GROUP BY
    C.Date
   ,C2.Country
OPTION
    ( MAXRECURSION 0 )
    ) lst
    ORDER BY lst.[Allocated testers] DESC
MaasSql
It looks so nice, but this is what my VS Studio tells me when putting it into the query builder:"Error in GROUP BY clause.Unable to parse query text."
Jack Johnstone
Hey, it works! What you have to do is putting " OPTION (MAXRECURSION 0)" as the absolutely last command :-)Thanks a big bunch!
Jack Johnstone
A: 

Leveraging existing query, just put another CTE on your existing query:

WITH Calendar AS (SELECT     CAST(@StartDate AS datetime) AS Date
                                          UNION ALL
                                          SELECT     DATEADD(d, 1, Date) AS Expr1
                                          FROM         Calendar AS Calendar_1
                                          WHERE     (DATEADD(d, 1, Date) < @EndDate))
 ,PeopleNeededPerCountry AS (
    SELECT     C.Date, C2.Country, COALESCE (SUM(R.[Amount of people per day needed]), 0) AS [Allocated testers]
     FROM         Calendar AS C CROSS JOIN
                            Country AS C2 LEFT OUTER JOIN
                            Requests AS R ON C.Date BETWEEN R.[Start date] AND R.[End date] AND R.CountryID = C2.CountryID
     WHERE     (C2.Country = @Country)
     GROUP BY C.Date, C2.Country OPTION (MAXRECURSION 0) 

  ) -- PeopleNeededPerCountry

 select max([Allocated testers]) /* or PeopleNeeded? */
 from PeopleNeededPerCountry
Michael Buen
This too looks nice, but this is what my VS Studio tells me when putting it into the query builder: "Unable to parse query text." I´ve tried to mess around with the code for a while, but with no success.
Jack Johnstone
+1  A: 

Full example following the discussion in @Salil answer..

WITH Calendar AS (SELECT     CAST(@StartDate AS datetime) AS Date
                  UNION ALL
                  SELECT     DATEADD(d, 1, Date) AS Expr1
                  FROM         Calendar AS Calendar_1
                   WHERE     (DATEADD(d, 1, Date) < @EndDate))
SELECT  TOP 1   C.Date, C2.Country, COALESCE (SUM(R.[Amount of people per day needed]), 0) AS [Allocated testers]
FROM    Calendar AS C CROSS JOIN
        Country AS C2 LEFT OUTER JOIN
        Requests AS R ON C.Date BETWEEN R.[Start date] AND R.[End date] AND R.CountryID = C2.CountryID
WHERE     (C2.Country = @Country)
GROUP BY C.Date, C2.Country 
ORDER BY 3 DESC
OPTION (MAXRECURSION 0)

the ORDER BY 3 means order by the 3rd field in the SELECT statement.. so if you remove the first two fields, change this accordingly..

Gaby
Very nice, thanks! I will check this out too, even if I got another valid answer some short time ago - and good info about ORDER BY 3. Did not know :-)
Jack Johnstone
So I guess "SELECT TOP..." and "ORDER BY ... DESC" are always to be glued together? ((Also,) I like the un-need of extra parenthesises (in your solution))
Jack Johnstone