views:

53

answers:

2

Hello!

I have two tables:

Unit:
UnitId int PK
Title varchar

UnitOption:
UnitOptionId int PK
UnitId int FK
Title varchar

Quote:
QuoteId int PK
UnitOptionId int FK
Title varchar

I want to create a scalar UDF that takes a QuoteId param and returns a varchar that contains the following description (pseudu):

Quote.Title + '-' + Unit.Title + '-' + Unit.UnitId + 
/* Here is where my question is:
If there are more than 1 UnitOption under this Unit, then
  return '-' + the UnitOption number under this Unit
  (i.e.) if under this Unit, there are 3 UnitOption with IDs 13, 17, 55
  under the unit, and the current Quote.UnitOptionId is the 17 one,
  it should return 2.
  Which means I want to retrieve an ID of this row in the group.
Else
  return ''
*/
A: 

If you're using SQL 2005 or later and I've interpreted your question correctly, you should be able to adapt the following into your function.

WITH [UnitExt] AS
(
    SELECT
        [Unit].[UnitId],
        [Unit].[Title],
        COUNT(*) AS [Count]
    FROM [Unit]
        INNER JOIN [UnitOption] ON [UnitOption].[UnitId] = [Unit].[UnitId]
    GROUP BY
        [Unit].[UnitId],
        [Unit].[Title]
)

SELECT
    [Quote].[Title] + '-' + [UnitExt].[Title] + '-' + [UnitExt].[UnitId] + 
        CASE
          WHEN [UnitExt].[Count] > 1 THEN '-' +
              CAST([UnitOption].[UnitOptionId] AS varchar(max))
          ELSE ''
      END
FROM [Quote]
    INNER JOIN [UnitOption] ON [UnitOption].[UnitOptionId] =
        [Quote].[UnitOptionId]
    INNER JOIN [UnitExt] ON [UnitExt].[UnitId] = [UnitOption].[UnitId]
WHERE [Quote].[QuoteId] = @QuoteId
Daniel Renshaw
I still didn't have the chance to test it but something looks wrong at the *"CAST([UnitExt].[Count] - 1 AS varchar(max))"* line, since, if count = 4 for instance, it will return 3 for all of them, whilst I want to return the current ID in the group, look at my question at the *(i.e.....)* line.So basically the solution must be selecting a semi-group-ID that represents the number of each row at this group.
Shimmy
That requirement wasn't clear to me and I felt it could go either way; looks like I plumped for the wrong one! I've changed it but I'm still not sure it's what you want.
Daniel Renshaw
A: 

Something like this should do it.

SELECT DISTINCT Quote.Title +
       ' - ' + Unit.Title +
       ' - ' + Unit.UnitId +
       CASE
           WHEN COUNT(*) OVER(PARTITION BY Quote.Id) > 0
       THEN
           ' - ' + CAST(ROW_NUMBER() OVER (PARTITION BY Quote.Id ORDER BY Quote.UnitOptionId) AS varchar)
       ELSE
           ''
       END
  FROM Quote
  JOIN UnitOption ON UnitOption.Id = Quote.UnitOptionId
  JOIN Unit ON Unit.Id = UnitOption.UnitId
 WHERE Quote.Id = @QuoteId
erikkallen