выберите имя столбца из максимального запроса - PullRequest
6 голосов
/ 02 октября 2010

У меня есть запрос, который выглядит примерно так:

 ;WITH t as
(
select 1 as RowNumber, 1 as ObjectID, 10 as [Col1],  20 as [Col2],  20 as [Col3],  20 as [Col4] UNION ALL
select 2 as RowNumber, 2 as ObjectID, 20 as [Col1],  30 as [Col2],  40 as [Col3],  50 as [Col4]
)
SELECT  RowNumber, ObjectID,
        (
        SELECT  MAX(Amount)
        FROM    (
                SELECT  [Col1] AS Amount
                UNION ALL
                SELECT  [Col2]
                UNION ALL
                SELECT  [Col3]
                UNION ALL
                SELECT  [Col4]
                ) d
       WHERE   Amount > 0
        )
FROM    t

Запрос работает нормально, но я хочу знать, откуда берется Max (Amount).

Итак, в моем наборе результатов, помимо наличия (RowNumber, ObjectId, Amount), я хочу, чтобы имя столбца (Col1, Col2, Col3, Col4) представляло собой строку.

Есть ли способ сделать это?

EDIT Вопрос из комментариев: если два столбца имеют одинаковый максимум, это может быть либо один? Да, это может быть один из них. Подойдет любое имя столбца, если я знаю, откуда оно.

Использование SQL Server 2008

Ответы [ 4 ]

5 голосов
/ 02 октября 2010

Don't MAX: используйте TOP, который избегает агрегирования / GROUP BY.

Он также может работать с дубликатами, используя WITH TIES

Я не уверен, что у вас был псевдо-код или подзапрос, но это должно делать то, что вы хотите

 SELECT TOP 1 -- WITH TIES if needed
     *
 FROM
     (
     SELECT  RowNumber, ObjectID, [Col1] AS Amount, 'Col1' AS ColName
     FROM table
     UNION ALL
     SELECT  RowNumber, ObjectID, [Col2], 'Col2' AS ColName
     FROM table
     UNION ALL
     SELECT  RowNumber, ObjectID, [Col3], 'Col3' AS ColName
     FROM table
     UNION ALL
     SELECT  RowNumber, ObjectID, [Col4], 'Col4' AS ColName
     FROM table
     ) foo
 WHERE   Amount > 0
 ORDER BY Amount DESC

Ваша главная проблема в том, что вам придется касаться таблицы 4 раза, независимо от того, как вы это делаете, потому что подзапрос возвращает только одно значение.Я также не вижу решения ROW_NUMBER (но, вероятно, оно есть ...: -)

3 голосов
/ 02 октября 2010

Это не проверено: однако, чтобы увидеть, что происходит с вашими данными, это может помочь. Не совсем качество производственного кода:

SELECT  RowNumber, ObjectID,
        (
        SELECT  MAX(Amount)
        FROM    (
                SELECT str([Col1]) + ", col1, " AS Amount
                UNION ALL
                SELECT str([Col2]) + ", col2" 
                UNION ALL
                SELECT str([Col3]) + ", col3"
                UNION ALL
                SELECT str([Col4]) + ", col4"
                )
        WHERE   Amount > 0
        )
FROM    table

str () - это функция "toString ()" вашей СУБД. Ваш SQL кажется довольно странным, какую СУБД вы используете?

2 голосов
/ 02 октября 2010

Добавление шага к ответу пользователя user202553

;WITH t1 as(
select 1 as RowNumber, 1 as ObjectID, 10 as [Col1],  20 as [Col2],  20 as [Col3],  20 as [Col4] UNION ALL
select 2 as RowNumber, 2 as ObjectID, 20 as [Col1],  30 as [Col2],  40 as [Col3],  50000045 as [Col4]
),
t2 as(
SELECT  RowNumber, ObjectID,
        (
        SELECT  TOP 1 CAST(C AS BINARY(4)) + CAST(Amount as BINARY(4)) 
        FROM    (
                SELECT 'Col1' AS C, [Col1] AS Amount
                UNION ALL
                SELECT 'Col2' AS C, [Col2]
                UNION ALL
                SELECT 'Col3' AS C, [Col3]
                UNION ALL
                SELECT 'Col4' AS C, [Col4]
                ) d
       WHERE   Amount > 0
       ORDER BY Amount desc
        ) AS Top1
FROM    t1
)
SELECT RowNumber, 
       ObjectID,
       CAST(Left(Top1, 4) AS CHAR(4)) AS Col, 
       CAST(SUBSTRING(Top1,5,4) AS INT) AS Amount
FROM t2
1 голос
/ 03 октября 2010

Вы можете использовать комбинацию UNPIVOT и OUTER APPLY :

;WITH t as     (
select 1 as RowNumber, 1 as ObjectID, 10 as [Col1],  20 as [Col2],  
       20 as [Col3],  20 as [Col4] UNION ALL
select 2 as RowNumber, 2 as ObjectID, 20 as [Col1],  30 as [Col2],  
       40 as [Col3],  50 as [Col4] )
SELECT 
  RowNumber,
  ObjectID,
  ColName,
  ColAmount
FROM t
OUTER APPLY (
  SELECT TOP 1 
    ColName,
    ColAmount
  FROM 
    (
      SELECT
        Col1,
        Col2,
        Col3,
        Col4
    ) x 
    UNPIVOT (
      ColAmount FOR ColName IN (Col1, Col2, Col3, Col4) 
    ) y
   WHERE ColAmount > 0
   ORDER BY ColAmount DESC
 ) z

Результаты:

RowNumber   ObjectID    ColName   ColAmount
----------- ----------- --------- -----------
1           1           Col2      20
2           2           Col4      50
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...