Отличительный вопрос по SQL Server - PullRequest
1 голос
/ 26 мая 2010

Мне нужно иметь возможность выбирать только первую строку для каждого имени, имеющего наибольшее значение.

У меня есть таблица со следующим:

id  name  value

0   JOHN  123
1   STEVE 125
2   JOHN  127
3   JOHN  126

Так что я хочу вернуться:

id  name  value

1   STEVE 125
2   JOHN  127

Есть ли какие-либо идеи о синтаксисе MSSQL о том, как выполнить эту операцию?

Ответы [ 5 ]

7 голосов
/ 26 мая 2010

Пока вы указали SQL Server, вы не указали версию. Если вы используете SQL Server 2005 или более позднюю версию, вы можете сделать что-то вроде:

With RankedItems As
    (
        Select id, name, value
            , Row_Number() Over ( Partition By name Order By value Desc, id Asc ) As ItemRank
        From Table
    )
Select id, name, value
From RankedItems
Where ItemRank = 1
2 голосов
/ 26 мая 2010

Вы могли бы сделать что-то вроде

SELECT id, name, value
FROM (SELECT id, name, value
             ROWNUMBER() OVER (PARTITION BY name ORDER BY value DESC) AS r
      FROM table) AS x
WHERE x.r = 1 ;

Это не будет работать в SQL Server 2000 и более ранних версиях, но это будет невероятно быстро в SQL Server 2005 и 2008

2 голосов
/ 26 мая 2010

попробовать:

SELECT
    MIN(id) as id,dt.name,dt.value
    FROM (SELECT
              name,MAX(value) as value
              FROM YourTable
              GROUP BY name
         ) dt
        INNER JOIN YourTable t ON dt.name=t.name and dt.value=t.value
    GROUP BY dt.name,dt.value

попробуйте:

DECLARE @YourTable table (id int, name varchar(10), value int)
INSERT @YourTable VALUES (0, 'JOHN',  123)
INSERT @YourTable VALUES (1, 'STEVE', 125)
INSERT @YourTable VALUES (2, 'JOHN',  127)
INSERT @YourTable VALUES (3, 'JOHN',  126)

--extra data not in the question, shows why you need the outer group by
INSERT @YourTable VALUES (4, 'JOHN',  127)
INSERT @YourTable VALUES (5, 'JOHN',  127)
INSERT @YourTable VALUES (6, 'JOHN',  127)
INSERT @YourTable VALUES (7, 'JOHN',  127)

SELECT
    MIN(id) as id,dt.name,dt.value
    FROM (SELECT
              name,MAX(value) as value
              FROM @YourTable
              GROUP BY name
         ) dt
        INNER JOIN @YourTable t ON dt.name=t.name and dt.value=t.value
    GROUP BY dt.name,dt.value
    ORDER BY id

Выход:

id          name       value
----------- ---------- -----------
1           STEVE      125
2           JOHN       127

(2 row(s) affected)
0 голосов
/ 26 мая 2010
SELECT a.id, a.name, a.value
  FROM mytbl a
 INNER JOIN (SELECT name, max(value) as maxvalue
               FROM mytbl
           GROUP BY name) b ON b.name = a.name and b.maxvalue = a.value
0 голосов
/ 26 мая 2010

Как насчет:

SELECT a.id, a.name, b.maxvalue
  FROM mytbl a
 INNER JOIN (SELECT id, max(value) as maxvalue
               FROM mytbl
           GROUP BY id) b ON b.id = a.id
...