Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рейтинг TOP2 по условию / 21 сообщений из 21, страница 1 из 1
25.12.2017, 14:43
    #39575504
RC88
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
Здравствуйте, помогите, пожалуйста с решением:

Есть одна таблица, например
Регион Человек Оценка
Москва Иванов 10
Москва Петров 5
Москва Путенова 7
Москва Песковинская 9
Пермь Смирнов 5
Пермь Петров 10
Пермь Петрова 15
Пермь Смирнова 20
и тд.

Нужно вывести для каждого региона по 2 человека с наименьшими оценками, например
Регион Человек Оценка
Москва Петров 5
Москва Путенова 7
Пермь Смирнов 5
Пермь Петров 10
...
Рейтинг: 0 / 0
25.12.2017, 14:44
    #39575505
Рейтинг TOP2 по условию
GROUP BY
...
Рейтинг: 0 / 0
25.12.2017, 14:45
    #39575507
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
Ого, уже второй человек с похожей задачей.
Экзамены што-ле?
...
Рейтинг: 0 / 0
25.12.2017, 15:08
    #39575531
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
Код: sql
1.
2.
3.
4.
5.
WITH CTE AS(SELECT *, N=ROW_NUMBER()OVER(PARTITION BY Регион ORDER BY Оценка))
SELECT Регион, Человек, Оценка
FROM CTE
WHERE N<3
ORDER BY Регион, Человек, Оценка;
...
Рейтинг: 0 / 0
25.12.2017, 15:12
    #39575533
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
iap
Код: sql
1.
2.
3.
4.
5.
WITH CTE AS(SELECT *, N=ROW_NUMBER()OVER(PARTITION BY Регион ORDER BY Оценка))
SELECT Регион, Человек, Оценка
FROM CTE
WHERE N<3
ORDER BY Регион, Человек, Оценка;

Как обычно, забыл FROM
Код: sql
1.
2.
3.
4.
5.
WITH CTE AS(SELECT *, N=ROW_NUMBER()OVER(PARTITION BY Регион ORDER BY Оценка) FROM Таблица)
SELECT Регион, Человек, Оценка
FROM CTE
WHERE N<3
ORDER BY Регион, Человек, Оценка;
...
Рейтинг: 0 / 0
26.12.2017, 10:09
    #39575877
RC88
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
iap,
Спасибо большое, все получилось!
С наступающим новым годом=)
...
Рейтинг: 0 / 0
26.12.2017, 10:37
    #39575894
Goga-Gola
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
RC88,

только экзаменатор может что-то заподозрить глядя на код :)
...
Рейтинг: 0 / 0
26.12.2017, 11:59
    #39575991
Jaffar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
Код: sql
1.
2.
3.
4.
5.
6.
7.
какие CTE -только подзапросы
select t."Регион", t."Человек", t."Оценка"
from (select t.*, row_number() over(partition by t."Регион" order by t."Оценка" asc) NN
	  from Tabel t with(nolock) /**/ ) t
where
		t.NN in (1, 2)
order by 1, 2, 3
...
Рейтинг: 0 / 0
26.12.2017, 12:04
    #39575995
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
Jaffar,

о, а вы поди думаете что это не одно и тоже?
...
Рейтинг: 0 / 0
26.12.2017, 12:44
    #39576025
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
TaPaKJaffar,

о, а вы поди думаете что это не одно и тоже?Строго говоря, наверно это не одно и то же.
Небось это обрабатывается разными фрагментами кода сервера.
Ведь синтаксис производной таблицы исключает, к примеру, рекурсию.
...
Рейтинг: 0 / 0
26.12.2017, 12:59
    #39576037
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
iap,

если брать конкретно эти примеры, то лпан и обработка будут очень похожи, а скорее одинаоквы. Еси брать рекурсию, то там тоже ничего особого, кроме table spool со значениями рекурсии. Так что тут больше вопрос организации операторов рекурсии.
...
Рейтинг: 0 / 0
26.12.2017, 13:09
    #39576047
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
TaPaKiap,

если брать конкретно эти примеры, то лпан и обработка будут очень похожи, а скорее одинаоквы. Еси брать рекурсию, то там тоже ничего особого, кроме table spool со значениями рекурсии. Так что тут больше вопрос организации операторов рекурсии.Вы видели программный код сервера?
В частности, относящийся к CTE и производной таблицы?
Уверен, что нет. Можем только гадать.
...
Рейтинг: 0 / 0
26.12.2017, 13:20
    #39576056
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
iapTaPaKiap,

если брать конкретно эти примеры, то лпан и обработка будут очень похожи, а скорее одинаоквы. Еси брать рекурсию, то там тоже ничего особого, кроме table spool со значениями рекурсии. Так что тут больше вопрос организации операторов рекурсии.Вы видели программный код сервера?
В частности, относящийся к CTE и производной таблицы?
Уверен, что нет. Можем только гадать.
ну нам доступен только план, на него и смотрим :)
...
Рейтинг: 0 / 0
27.12.2017, 09:41
    #39576552
__Avenger__
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
select top 2 with ties t.*
from Tabel t with(nolock)
order by row_number() over(partition by t."Регион" order by t."Оценка" asc), 1, 2, 3[/SRC]

?
...
Рейтинг: 0 / 0
27.12.2017, 09:50
    #39576557
ptr128
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
__Avenger__select top 2 with ties t.*
[/SRC]

Ваш запрос всегда будет выдавать две записи. А вовсе не по две записи для каждого региона.
...
Рейтинг: 0 / 0
27.12.2017, 09:53
    #39576560
__Avenger__
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
ptr128,

Да, а если проверить? Про WITH TIES слышал?
...
Рейтинг: 0 / 0
27.12.2017, 11:17
    #39576642
ptr128
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
__Avenger__,

Конечено слышал. Он к данной задаче не имеет никакого отношения, так как ТС прости 2 человека, без детерминированности.
Сравните результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
IF EXISTS (SELECT 1 FROM sysobjects WHERE name=N'Tabel' and type='U') DROP TABLE Tabel
CREATE TABLE Tabel (
  [Человек] nvarchar(50),
  [Регион] nvarchar(30),
  [Оценка] int
)
GO
DECLARE
  @I int = 10000
BEGIN TRAN
WHILE @I>0 BEGIN
  INSERT Tabel ([Человек], [Регион], [Оценка])
    VALUES (N'Name'+CONVERT(nvarchar(11),@I)+N' Middlename'+CONVERT(nvarchar(11),@I)+
	  N' Lastname'+CONVERT(nvarchar(11),@I),
	  N'Name'+CONVERT(nvarchar(11),CONVERT(int,RAND()/0.1*10)), CONVERT(int,RAND()/0.1*10)
	)
  SELECT @I=@I-1
END
COMMIT TRAN
GO

select top 2 with ties t.*
from Tabel t with(nolock)
order by row_number() over(partition by t."Регион" order by t."Оценка" asc), 1, 2, 3

SELECT [Регион], [Человек], [Оценка]
FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY [Регион] ORDER BY [Оценка]) AS N FROM Tabel) Q
WHERE N<3
ORDER BY [Регион], [Человек], [Оценка]
...
Рейтинг: 0 / 0
27.12.2017, 11:51
    #39576686
over,
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
ptr128Сравните результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
IF EXISTS (SELECT 1 FROM sysobjects WHERE name=N'Tabel' and type='U') DROP TABLE Tabel
CREATE TABLE Tabel (
  [Человек] nvarchar(50),
  [Регион] nvarchar(30),
  [Оценка] int
)
GO
DECLARE
  @I int = 10000
BEGIN TRAN
WHILE @I>0 BEGIN
  INSERT Tabel ([Человек], [Регион], [Оценка])
    VALUES (N'Name'+CONVERT(nvarchar(11),@I)+N' Middlename'+CONVERT(nvarchar(11),@I)+
	  N' Lastname'+CONVERT(nvarchar(11),@I),
	  N'Name'+CONVERT(nvarchar(11),CONVERT(int,RAND()/0.1*10)), CONVERT(int,RAND()/0.1*10)
	)
  SELECT @I=@I-1
END
COMMIT TRAN
GO

select top 2 with ties t.*
from Tabel t with(nolock)
order by (row_number() over(partition by t."Регион" order by t."Оценка" asc) - 1) / 2 --, 1, 2, 3

SELECT [Регион], [Человек], [Оценка]
FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY [Регион] ORDER BY [Оценка]) AS N FROM Tabel) Q
WHERE N<3
ORDER BY [Регион], [Человек], [Оценка]
...
Рейтинг: 0 / 0
27.12.2017, 12:03
    #39576702
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
over,ptr128Сравните результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
IF EXISTS (SELECT 1 FROM sysobjects WHERE name=N'Tabel' and type='U') DROP TABLE Tabel
CREATE TABLE Tabel (
  [Человек] nvarchar(50),
  [Регион] nvarchar(30),
  [Оценка] int
)
GO
DECLARE
  @I int = 10000
BEGIN TRAN
WHILE @I>0 BEGIN
  INSERT Tabel ([Человек], [Регион], [Оценка])
    VALUES (N'Name'+CONVERT(nvarchar(11),@I)+N' Middlename'+CONVERT(nvarchar(11),@I)+
	  N' Lastname'+CONVERT(nvarchar(11),@I),
	  N'Name'+CONVERT(nvarchar(11),CONVERT(int,RAND()/0.1*10)), CONVERT(int,RAND()/0.1*10)
	)
  SELECT @I=@I-1
END
COMMIT TRAN
GO

select top 2 with ties t.*
from Tabel t with(nolock)
orderby(row_number()over(partition byt."Регион" orderbyt."Оценка" asc)-1)/2 --, 1, 2, 3

SELECT [Регион], [Человек], [Оценка]
FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY [Регион] ORDER BY [Оценка]) AS N FROM Tabel) Q
WHERE N<3
ORDER BY [Регион], [Человек], [Оценка]


Тогда уж надо TOP(1), а не TOP(2)
...
Рейтинг: 0 / 0
27.12.2017, 12:12
    #39576711
ptr128
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
iapover,пропущено...
Тогда уж надо TOP(1), а не TOP(2)
Ну я скопировал код один к одному, чтобы у автора не было претензий )
...
Рейтинг: 0 / 0
27.12.2017, 12:13
    #39576713
ptr128
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рейтинг TOP2 по условию
__Avenger__ptr128,

Да, а если проверить? Про WITH TIES слышал?

Приношу извинения. Был не прав. Действительно детерменирование номера строки позволяет добиться требуемого результата.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рейтинг TOP2 по условию / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]