Получить индекс строки в группе? - PullRequest
0 голосов
/ 19 августа 2010

У меня есть две таблицы:

Unit:
UnitId int PK
Title varchar

UnitOption:
UnitOptionId int PK
UnitId int FK
Title varchar

Quote:
QuoteId int PK
UnitOptionId int FK
Title varchar

Я хочу создать скалярный UDF, который принимает параметр QuoteId и возвращает varchar, который содержит следующее описание (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 ''
*/

Ответы [ 3 ]

0 голосов
/ 22 августа 2010

Что-то вроде этого должно сделать это.

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
0 голосов
/ 19 ноября 2010
CREATE FUNCTION ufnGetDescription 
  (@QuoteID INT) 
RETURNS VARCHAR(MAX) 
AS 
  BEGIN 
  DECLARE @RetVal VARCHAR(MAX); 

  WITH CurRow 
  AS (SELECT quote.title + '- ' + unit.title AS start, 
    u.unitid, 
    quoteid, 
    uo.unitoptionid 
  FROM quote 
    INNER JOIN unitoption uo 
    ON quote.unitoptionid = uo.unitoptionid 
    INNER JOIN unit 
    ON uo.unitid = unit.unitid 
  WHERE quote.quoteid = @QuoteID), 
  AllUnits 
  AS (SELECT u.unitid, 
    uo.unitoptionid, 
    Row_number() 
    OVER(PARTITION BY u.unitid ORDER BY uo.unitoptionid) AS NUMBER, 
    Count(* ) 
    OVER(PARTITION BY u.unitid )  AS cntUnits 
  FROM unit 
    INNER JOIN unionoption uo 
    ON unit.unitid = uo.unitid 
  WHERE u.unitid IN (SELECT unitid 
      FROM CurRow)) 
  SELECT @RetVal = CASE 
    WHEN a.cntUnits = 1 THEN '' 
    ELSE r.start + '-' + Cast(NUMBER AS VARCHAR(max)) 
    END 
  FROM AllUnits a 
  INNER JOIN CurRow r 
  ON a.unitoptionid = r.unitoptionid 

  RETURN @RetVal 
END
0 голосов
/ 19 августа 2010

Если вы используете SQL 2005 или более позднюю версию, и я правильно истолковал ваш вопрос, вы сможете адаптировать следующее к своей функции.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...