powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Такая вот задачка
20 сообщений из 20, страница 1 из 1
Такая вот задачка
    #32035643
Фотография VVG_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть табличка товаров (PID, PName), таблица категорий (CID,CName) и промежуточная табличка привязок (PID,CID). Товар может быть привязан к нескольким категориям.

Задача - придумать запрос, который бы возвращал в результате по одной записи на товар, но с перечислением названий всех категорий с произвольным разделителем.

То есть, что-то примерно такое:
(PID,CName1[+','+CName2[+','+...]]).

Как бы так сэмулировать аггрегирующую функцию контенкации строк? Чего-то с ходу ничего не получается, а было это или нет в форуме - не помню.

О переполнении varchar просьба не задумываться. :)

Надеюсь на помощь. :)
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035649
guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для SQL 200 примерно, вот так:
Код: plaintext
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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
create table Titles (PID  int primary key, PName varchar( 10 ))
go
insert into Titles values ( 1 ,'Title1')
insert into Titles values ( 2 ,'Title2')
insert into Titles values ( 3 ,'Title3')

create table Categories (CID  int primary key, CName varchar( 10 ))
go

insert into Categories values ( 1 ,'Cat1')
insert into Categories values ( 2 ,'Cat2')
insert into Categories values ( 3 ,'Cat3')


create table TitlesCategories (PID int not NULL, CID  int not NULL)
go
alter table TitlesCategories add constraint
PK_TitlesCategories primary key clustered (pid,cid)
go

insert into TitlesCategories values ( 1 , 1 )
insert into TitlesCategories values ( 1 , 2 )
insert into TitlesCategories values ( 1 , 3 )
insert into TitlesCategories values ( 2 , 2 )
insert into TitlesCategories values ( 3 , 1 )
insert into TitlesCategories values ( 3 , 3 )
go


CREATE FUNCTION [dbo].[fn_strSum] (@PID int, @separator char( 1 )) 
RETURNS varchar( 8000 )
AS
BEGIN
	declare @result varchar( 8000 )
	set @result = ''
	
	select @result = coalesce(t3.CName,'') + @separator + @result
	from Titles t1
	inner join TitlesCategories t2
	on t1.PID = t2.PID
	inner join Categories t3
	on t2.CID = t3.CID
	where t1.PID = @PID

if Len(@result) >  0 
	set @result =  substring(@result,  1 , len(@result)- 1 )
else
	set @result = NULL
return @result
END
go


select PID, [dbo].[fn_strSum] (PID, ':')  from Titles



drop function fn_strSum
go
drop table TitlesCategories, Titles, Categories
go


...
Рейтинг: 0 / 0
Такая вот задачка
    #32035655
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Плохо. Когда прут повторы. Тов. jimmers когда-то блестяще ответил на этот вопрос.

P.S. Товарищ Guest! А что делать тем, у кого SQL Server 7.0???
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035658
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для тех, у кого SQL 7.
Правда только для выборки по одному наименованию.

Код: plaintext
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.
30.
31.
32.
33.
create table P (PID int, PName char ( 1 ) )
create table C (CID int, CName char ( 2 ) )
create table R (PID int, CID int)

insert P values ( 1 ,'a')
insert P values ( 2 ,'b')

insert C values ( 1 ,'c1')
insert C values ( 2 ,'c2')
insert C values ( 3 ,'c3')

insert R values ( 1 , 1 )
insert R values ( 1 , 2 )
insert R values ( 1 , 3 )

insert R values ( 2 , 1 )

select PName,CName,convert(varchar( 500 ),NULL) as Contact into #temp from P
join R on P.PID=R.PID
join C on R.CID=C.CID
where P.PID= 1 

declare @Contact varchar( 500 )
set @Contact = ''

update #temp set @Contact=Contact=@Contact + ISNULL(CName, '')+','

select PName,max(Contact) from #temp
group by PName
 
drop table #temp
drop table P
drop table C
drop table R
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035706
guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Плохо. Когда прут повторы.

Если речь идет об этой довольно незатейливой функции, то я ее написал года полтора назад. Если у jimmers получилось то же самое и решение признано блестящим, я только рад.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035712
smart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
create table Titles (PID int primary key, PName varchar(10))
go
insert into Titles values (1,'Title1')
insert into Titles values (2,'Title2')
insert into Titles values (3,'Title3')

create table Categories (CID int primary key, CName varchar(10))
go

insert into Categories values (1,'Cat1')
insert into Categories values (2,'Cat2')
insert into Categories values (3,'Cat3')


create table TitlesCategories (PID int not NULL, CID int not NULL)
go
alter table TitlesCategories add constraint
PK_TitlesCategories primary key clustered (pid,cid)
go

insert into TitlesCategories values (1,1)
insert into TitlesCategories values (1,2)
insert into TitlesCategories values (1,3)
insert into TitlesCategories values (2,2)
insert into TitlesCategories values (3,1)
insert into TitlesCategories values (3,3)
go

create table Result (PID int not NULL, PName varchar(255), ResName varchar(255) not NULL)
go

declare @PID int, @PName varchar(20), @CID int, @CName varchar(20), @Result varchar(255)

declare TitleCur cursor for
select PID, PName from Titles
open TitleCur
fetch TitleCur into @PID, @PName

while @@fetch_status = 0
begin
declare CatCur cursor for
select c.CID, CName from Categories c join TitlesCategories tc on tc.CID = c.CID and PID = @PID

open CatCur
set @Result = ''
fetch CatCur into @CID, @CName
while @@fetch_status = 0
begin
set @Result = @Result + case @Result when '' then '' else ', ' end + @CName
fetch CatCur into @CID, @CName
end
insert into Result values (@PID, @PName, @Result)
deallocate CatCur
fetch TitleCur into @PID, @PName
end
select * from Result
deallocate TitleCur

drop table Titles
drop table TitlesCategories
drop table Categories
drop table Result
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035737
Фотография VVG_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо всем откликнувшимся, сейчас проверю все варианты и сообщу результаты. :)
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035755
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тов. Guest!
Слово "повторы" относится к сути вопроса, а не к способу решения. Просекли?
Насчет блеска решения тов. Джиммерса. У товарища Джиммерса все решения блестящие (даже которые неправильные). Потому как дарование. Вам до него далеко (я надеюсь).
P.S. Впредь постарайтесь не выводить меня из себя. Не надо.
P.P.S. А впрочем, как хотите. Можете ещё какую-нибудь гадость мне написать.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035788
Фотография VVG_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уточню условия задачи:

Есть unique constraint (PID,CID) на TitlesCategories. На выходе нужны только те продукты, которые привязаны хотя бы к одной категории. Порядок перечисления несущественен.

Условия тестирования:

В таблице Titles примерно 22000 записей. Основные индексы присутствуют. MSSQL 2000 SP2, Windows NT 4.0 SP6, Intel Celeron 500. Все запросы выполнялись из QA на предварительно "разогретом" сервере.

Вариант 1 (только 2000).

Код: plaintext
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.
30.
create table result1 (pid int,res varchar( 8000 ))
go
create function [dbo].[fn_strSum] (@PID int, @separator char( 1 )) 
returns varchar( 8000 )
as
begin
	declare @result varchar( 8000 )
	set @result = ''
	
	select @result = coalesce(t3.CName,'') + @separator + @result
	from Titles t1
	inner join TitlesCategories t2
	on t1.PID = t2.PID
	inner join Categories t3
	on t2.CID = t3.CID
	where t1.PID = @PID

if Len(@result) >  0 
	set @result =  substring(@result,  1 , len(@result)- 1 )
else
	set @result = null
return @result
end
go
insert into result1 select PID, [dbo].[fn_strSum] (PID, ',')  from Titles

select * from result1 where res is not null

drop function [dbo].[fn_strSum]

drop table result1

Среднее время выполнения запроса - 11 секунд.

Вариант 2 (должен работать на 7.0). Его я несколько доработал для получения правильных результатов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
create table result2 (pid int,cname varchar( 200 ),res varchar( 7800 ))

create unique clustered index ix_result2 on result2 (pid,cname)

insert into result2 select t1.pid,t2.cname,'' from TitlesCategories t1
inner join Categories t2 on t1.CID=t2.CID
order by t1.pid,t2.cname

declare @Contact varchar( 8000 ),@PID int
set @Contact = '' set @pid= 0 

update result2 set @Contact=res=case when @PID=PID then CName+','+@Contact else CName end, @PID=PID

select pid,max(res) from result2 group by pid

drop table result2

Среднее время выполнения запроса - 10 секунд.

Ну и ради интереса вариант 3 (курсор).

Код: plaintext
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.
30.
31.
32.
create table result3 (PID int, Res varchar( 8000 )) 
go 
set nocount on
go
declare @PID int, @CID int, @CName varchar( 20 ), @Result varchar( 255 ) 

declare TitleCur cursor for 
select PID from Titles 
open TitleCur 
fetch TitleCur into @PID

while @@fetch_status =  0  
begin 
declare CatCur cursor for 
select c.CID, c.CName from Categories c join TitlesCategories tc on tc.CID = c.CID and PID = @PID 

open CatCur 
set @Result = '' 
fetch CatCur into @CID, @CName 
while @@fetch_status =  0  
begin 
set @Result = @Result + case @Result when '' then '' else ', ' end + @CName 
fetch CatCur into @CID, @CName 
end 
insert into result3 values (@PID, @Result) 
deallocate CatCur 
fetch TitleCur into @PID
end 
select * from result3 
deallocate TitleCur 

drop table result3

Среднее время выполнения запроса - 65 секунд.

Еще раз спасибо всем откликнувшимся, буду рад если эти результаты окажутся полезными еще кому-нибудь. :)

2 Guest & RatTail Слово "повторы" в первом чтении я понял как случай двойной привязки товара к одной категории, что видимо относится именно к сути вопроса. И давайте не будем поднимать вопросы первенства и копирайтов в моих топиках. :)
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035800
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Товарищ VVG_!
Более умного человека, чем Вы, я в своей жизни не встречал (чего и Вам желаю). Это вполне серьёзно. Поясню.
Я собираю в БД ответы (и вопросы) посетителей этого форума и потом с помощью очень хитрой проги (не мной написанной, конечно) провожу лексический (и не только) анализ текстов. На выходе получаю оценку IQ того или иного чела. Так вот, Вы уже давно занимаете первое место.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035802
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не секрет, то что за програмка ? И по какому принципу она работает ? Можно задать область область знаний ? Выбрать анализируемый язык ? Пунктуация учитывается ?

ЗЫ
Надеюсь, что это не "гон" ? :-)
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035810
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не секрет, то что за програмка ? И по какому принципу она работает ? Можно задать область область знаний ? Выбрать анализируемый язык ? Пунктуация учитывается ?

ЗЫ
Надеюсь, что это не "гон" ? :-)
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035815
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Glory
Если бы кто другой спросил (Cat2 не в счет, он мой друг (Rat&Cat - не хило, правда?)), я бы ещё "помучил". А Вам отвечу сразу:
My Lord, Glory, конечно же, это гон. И если кто Вам скажет, что такие проги есть (или могут быть), плюньте ему в морду. Такие проги из разряда кремлёвских таблеток и чудо-люстр афериста от науки Чижевского и успешно измерить могут только собачьи задницы.

P.S. Никогда и никому не позволяйте измерять Ваш IQ (и сами не меряйте).
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035839
Фотография VVG_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый RatTail.

Я был бы Вам очень признателен, если бы Вы не проводили на мне так любимые Вами психологические эксперименты.

Заранее спасибо.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035872
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как любитель офтопиков, не могу не встрять.
IQ, конечно, по формальному содержанию писем не определишь.
Но можно.
1. Определить базовый словарь. Чем он больше, тем вероятнее, что человек много читает. Тут есть некоторая корреляция с инетеллектом.
2. Определить частотное распределение слов. Наличие во главе списка слова "блин" дает некоторое понятие об воспитании.
3. Количество слов с ошибками свидетельствует о невнимательности и неаккуратности (это я про себя).
4. Чисто интернетовский признак. Частое использование смайликов говорит о неуверенном владении письменным литературным языком (неважно каким).
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035876
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2VVG_
Не надо ники менять. Я вот, пусть даже ещё "раз" трижды "опозорюсь", а свой ник не поменяю. И не от большой любви к нему.
2Cat2
Вы, как всегда, на высоте.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035887
Smile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4 Cat2

Блин, а че воспитание может на IQ сказываться?
Обычно вместо блин я говорю по другому, просто из уважения к посетителям форума....
Да и вообще, я думаю, что то, о чем вы говорите в своем посте, на этом форуме не главное. Наверное вы блины просто не любите.

А может количество слов с ошибками свидетельствует о неграмотности?

Как раз то вы очень внимательный, если про блины заметели, блин.

А смайликами злоупотреблять обычно любят девочки.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035888
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый Smile! Во-первых, "IQ" - это искусственный показатель, мало что говорящий об истинном интеллектуальном потенциале, и естественно воспитание на него влияет, как цены на мандарины в Батуми. Но плохо воспитанный человек может быть отторгнут интеллектуальной средой, что может помешать его профессиональному росту. (В 15 лет я проверился по этой буржуазной методике. Там, где начались мои результаты - шкала уже была закончена, а экстраполировать я еще не умел. Ну и что? Где моя Нобелевская премия? Просто я здорово натаскался на решении задач "Психологический практикум" из журнала "Наука и жизнь")

Разумеется, такие постинги, как мой предыдущий (и этот), совсем не главное на этом форуме.
Glory поинтересовался морфологической программой. По первым двум пунктам такие программы есть.

Ваши "блины" я не заметил. Просто сейчас очень распространенное слово-паразит.

Количество слов с ошибками необязательно говорит о неграмотности. Совсем уж неграмотные в форумы не пишут. Однако не проверить за собой текст - это неаккуратность, а не заметить в нем опечатки - невнимательность.

Насчет смайликов Вы правы, поэтому писателей гораздо больше, чем писательниц.
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035889
Smile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4 Cat2
Лучше посмотрите, пожалуйста, мои последние посты, чем рассуждать на тему: "Как грамотно сотовлять отправляемые в форум вопросы"
...
Рейтинг: 0 / 0
Такая вот задачка
    #32035890
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну не смотрел, я Ваши посты! У меня форум развлечение, а не работа! Сейчас гляну, что там.

Посмотрел.

Все кроме "Обрезания", к моим интересам имеет весьма слабое отношение. И я считаю себя недостаточно компетентным для ответов на вопросы по администрированию. Ляпну какую-нибудь муру, а у Вас сервак рухнет и Вас с работы попрут. Я разработчик.

Про "обрезание". Я уж не буду вылезать из этого топика, да простит меня VVG_.
А фиг его знает. Сразу не вспомню, это где-то в настройках сервера, что-то там есть про PADDING. Мне за Вас в БОЛ влезть и прочитать это?
Да и один черт, этот PADDING у меня правильно настроен и а помогает не всегда. У меня на клиенте к полям varchar добавляются символы перевода каретки. Вот это круто. Причем иногда спереди. Вторую неделю разбираюсь.
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Такая вот задачка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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