Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SQL задача  [new]
Aristes
Member

Откуда: Казахстан, Караганда
Сообщений: 85
Дана следующая таблица. Где год (дата поступления), группа (номер группы), итого (заплатили за учебу).

YearS	GroupS	TotalS
2003	A0301	43044
2003	B0324	33450
2003	B0325	34500
2003	C0321	50000
2003	D0301	-49909
2003	D0302	50087
2005	A0501	470
2005	A0502	570
2005	B0502	-140
2005	C0513	50000
2005	C0513	678
2005	D0501	-500
2006	A0601	130
2006	A0602	130
2006	B0699	15799
2006	C0698	14888
2006	C0699	-13000
2006	D0675	500


Имеется таблица "справочник" с латинским алфавитом.

Выполнить sql-запрос чтобы получить в следующем виде!

YearS	A	B	C	D
2003	43044	67950	50000	178
2005	1040	-140	50678	-500
2006	260	15799	1888	500


Для меня это не сложно если можно было бы использовать например Delphi или C++ но получить такие данные только с помощью SQL-запроса!

Прошу помогите чайнику в вопросах SQL! Спасибо за ранее!
1 июл 13, 11:03    [14503805]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Glory
Member

Откуда:
Сообщений: 104751
Aristes
Прошу помогите чайнику в вопросах SQL! Спасибо за ранее!

Вам нужен SELECT и функции SUM и CASE
1 июл 13, 11:07    [14503827]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Aristes

Прошу помогите чайнику в вопросах SQL! Спасибо за ранее!

Приблизительно так.
/*Создаем и заполняем таблицу*/
create table #tmp(YearS int,GroupS varchar(10),totalS int)
Insert #tmp

SELECT 2003,'A0301',43044
UNION ALL SELECT 2003,'B0324',33450
UNION ALL SELECT 2003,'B0325',34500
UNION ALL SELECT 2003,'C0321',50000
UNION ALL SELECT 2003,'D0301',-49909
UNION ALL SELECT 2003,'D0302',50087
UNION ALL SELECT 2005,'A0501',470
UNION ALL SELECT 2005,'A0502',570
UNION ALL SELECT 2005,'B0502',-140
UNION ALL SELECT 2005,'C0513',50000
UNION ALL SELECT 2005,'C0513',678
UNION ALL SELECT 2005,'D0501',-500
UNION ALL SELECT 2006,'A0601',130
UNION ALL SELECT 2006,'A0602',130
UNION ALL SELECT 2006,'B0699',15799
UNION ALL SELECT 2006,'C0698',14888
UNION ALL SELECT 2006,'C0699',-13000
UNION ALL SELECT 2006,'D0675',500
/*Делаем выборку*/
select years, SUM(CASE WHEN LEFT(GroupS,1)='A' THEN totalS ELSE 0 END) as 'A',
			  SUM(CASE WHEN LEFT(GroupS,1)='B' THEN totalS ELSE 0 END) as 'B',
			  SUM(CASE WHEN LEFT(GroupS,1)='C' THEN totalS ELSE 0 END) as 'C',
			  SUM(CASE WHEN LEFT(GroupS,1)='D' THEN totalS ELSE 0 END) as 'D'
from #tmp
group by years

/*Удаляем временную таблицу*/
drop table #tmp
1 июл 13, 11:24    [14503913]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Aristes
Member

Откуда: Казахстан, Караганда
Сообщений: 85
Glory
Aristes
Прошу помогите чайнику в вопросах SQL! Спасибо за ранее!

Вам нужен SELECT и функции SUM и CASE

SUM - это конечно понятно. Но вот CASE имеется ли более элегантный метод? И что бы перевернуть таблицу надо ли использовать PIVOT?
1 июл 13, 11:26    [14503929]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Aristes
Member

Откуда: Казахстан, Караганда
Сообщений: 85
Сергей Викт.
Aristes
Прошу помогите чайнику в вопросах SQL! Спасибо за ранее!

Приблизительно так.
/*Создаем и заполняем таблицу*/
create table #tmp(YearS int,GroupS varchar(10),totalS int)
Insert #tmp

SELECT 2003,'A0301',43044
UNION ALL SELECT 2003,'B0324',33450
UNION ALL SELECT 2003,'B0325',34500
UNION ALL SELECT 2003,'C0321',50000
UNION ALL SELECT 2003,'D0301',-49909
UNION ALL SELECT 2003,'D0302',50087
UNION ALL SELECT 2005,'A0501',470
UNION ALL SELECT 2005,'A0502',570
UNION ALL SELECT 2005,'B0502',-140
UNION ALL SELECT 2005,'C0513',50000
UNION ALL SELECT 2005,'C0513',678
UNION ALL SELECT 2005,'D0501',-500
UNION ALL SELECT 2006,'A0601',130
UNION ALL SELECT 2006,'A0602',130
UNION ALL SELECT 2006,'B0699',15799
UNION ALL SELECT 2006,'C0698',14888
UNION ALL SELECT 2006,'C0699',-13000
UNION ALL SELECT 2006,'D0675',500
/*Делаем выборку*/
select years, SUM(CASE WHEN LEFT(GroupS,1)='A' THEN totalS ELSE 0 END) as 'A',
			  SUM(CASE WHEN LEFT(GroupS,1)='B' THEN totalS ELSE 0 END) as 'B',
			  SUM(CASE WHEN LEFT(GroupS,1)='C' THEN totalS ELSE 0 END) as 'C',
			  SUM(CASE WHEN LEFT(GroupS,1)='D' THEN totalS ELSE 0 END) as 'D'
from #tmp
group by years

/*Удаляем временную таблицу*/
drop table #tmp


Гениально! Не думал что это можно сделать. Но как запихнуть данные во временную таблицу если у меня их больше чем в приведенном примере? Заранее спасибо!
1 июл 13, 11:30    [14503957]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Glory
Member

Откуда:
Сообщений: 104751
Aristes
Но вот CASE имеется ли более элегантный метод?

"Много букаф" что ли ? Или в чем мерять элегантность ?

Aristes
И что бы перевернуть таблицу надо ли использовать PIVOT?

Откуда это известно, если вы не сообщаете версию вашего сервера ?
1 июл 13, 11:30    [14503962]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Aristes
Member

Откуда: Казахстан, Караганда
Сообщений: 85
Glory,

"Много букаф" что ли ? Или в чем мерять элегантность ?

- Согласен вопрос о палке с двумя концами.

Откуда это известно, если вы не сообщаете версию вашего сервера ?

- Прошу прощения за неточности. Microsoft SQL Server 2008 Express Edition
1 июл 13, 11:33    [14503982]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
PaulYoung
Member

Откуда: Москва
Сообщений: 2567
Aristes
Но как запихнуть данные во временную таблицу если у меня их больше чем в приведенном примере?
Временная таблица - это для примера Вам-то нужно брать ВАШИ данные...
1 июл 13, 11:45    [14504077]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Aristes,

Достаточно простой запрос,
group by YearS

И три суммы с CASE внутри.
1 июл 13, 12:15    [14504310]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
Но вот CASE имеется ли более элегантный метод?

CaSE — очень элегантный метод.
1 июл 13, 12:17    [14504324]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Aristes
Member

Откуда: Казахстан, Караганда
Сообщений: 85
PaulYoung,

Пляяя я тупица! Невысыпание вредит!
Остался один маленький вопрос.
Aristes
...
Имеется таблица "справочник" с латинским алфавитом.
...


Как её использовать вместо оборота:

     , sum(CASE
         WHEN left(WareHouse, 1) = 'A' THEN
           TotalStock
         ELSE
           0
       END) AS 'A'


Ну т.е. не вбивать весь алфавит в запрос а использовать готовые данные...
1 июл 13, 12:17    [14504329]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Aristes
PaulYoung,

Пляяя я тупица! Невысыпание вредит!
Остался один маленький вопрос.
Aristes
...
Имеется таблица "справочник" с латинским алфавитом.
...


Как её использовать вместо оборота:

     , sum(CASE
         WHEN left(WareHouse, 1) = 'A' THEN
           TotalStock
         ELSE
           0
       END) AS 'A'


Ну т.е. не вбивать весь алфавит в запрос а использовать готовые данные...

Имею смелость предположить, что динамическим запросом.
1 июл 13, 12:21    [14504348]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
MasterZiv
Но вот CASE имеется ли более элегантный метод?

CaSE — очень элегантный метод.
Не, ну с пивотом-то попроще выглядит... разве нет?
;WITH myTemp AS (SELECT * FROM (VALUES 
	(2003,'A0301',43044), (2003,'B0324',33450), (2003,'B0325',34500),
	(2003,'C0321',50000), (2003,'D0301',-49909), (2003,'D0302',50087),
	(2005,'A0501',470), (2005,'A0502',570), (2005,'B0502',-140),
	(2005,'C0513',50000), (2005,'C0513',678), (2005,'D0501',-500),
	(2006,'A0601',130), (2006,'A0602',130), (2006,'B0699',15799),
	(2006,'C0698',14888), (2006,'C0699',-13000), (2006,'D0675',500)
	) AS temp_myTemp([YearS],[GroupS],[totalS]))
select * from (
   select YearS, chr, totalS
   from myTemp t
   cross apply (select LEFT(GroupS,1) chr ) c
   )s
pivot(sum(totalS) for chr in ([A],[B],[C],[D],[E],[F],[G],[H],[I],[J]))p
1 июл 13, 12:32    [14504448]     Ответить | Цитировать Сообщить модератору
 Re: SQL задача  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Зачем это на скуле?
Всё это делает автоматом с полпинка: Excel, PowerPivot, подключить источник, SQL запрос.
Не надо тут никаких динамических запросов. Скуль не для этого.
автор
LEFT(GroupS,1)='B'
Чё так сложно и зачем путать скуль?!
GroupS LIKE 'B%'
1 июл 13, 12:41    [14504523]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить