powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Интересная задача при связи "многие-ко-многим"
20 сообщений из 20, страница 1 из 1
Интересная задача при связи "многие-ко-многим"
    #32565177
Andronov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Есть такая задача:
Есть ЛЮДИ и есть КАТЕГОРИИ. Связаны они как многие-со-многими. Нужно иметь возможность показать количество ЛЮДЕЙ в КАТЕГОРИИ. В таком виде все понятно - записываем в таблицу фактов все факты о том, что у ЧЕЛ. есть КАТ. и агрегируем по DISTINCT COUNT.

Проблемы начинаются тогда, когда возникает вопрос "Сколько ЛЮДЕЙ относятся ОДНОВРЕМЕННО к 2 или более определенным КАТЕГОРИЯМ"

Есть идея для каждой категории ввести свое измерение со значениями "Есть/Нет", но при этом мы привязываем стуктуру таблицы фактов к составу набора КАТЕГОРИЙ.

Может, есть какие-нибудь более простые решения? Кто-нибудь сталкивался с такой задачей?
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565388
Jurii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я такие задачи решаю в OLAP-клиенте Cognos PowerPlay с помощью функции Свертка (поскольку показатель типа Distinct Count - неаддитивен, и его нельзя складывать, а можно только сворачивать). При этом OLAP-сервер тоже надо с умом выбирать - не все сервера отработают операцию свертки - по крайней мере MS AS научится это делать только с выходом Юкона (где-то через год).
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565422
Andronov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MS AS замечательно "сворачивает", как вы выразились, при помощи той самой агрегации DISTINCT COUNT. Вопрос был в том, как вычислить число элементов в одной "свертке", которые при этом попадают в другую "свертку".
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565482
Jurii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Andronov:

MS AS замечательно "сворачивает", как вы выразились

Действительно, Ваша задача посложнее чем обычная свертка...
Рассмотрим следующий пример:
Человек, Категория
Иванов, Слесарь
Иванов, Студент
Петров, Слесарь
Петров, Кассир
Сидоров, Кассир

Слесарей - 2
Студентов - 1
Кассиров - 2

Правильно ли я понимаю, что Вам надо получить:
людей которые являются и слесарями и кассирами - 1
?
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565697
Andronov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Абсолютно верно. Слесарь-кассир - 1 - Петров.
Еще лучше было бы иметь возможность спрашивать примерно так:
Сколько у нас слесарей? - 2
А сколько из них кассиров? - 1

Приемлемое количество таких уровней для нашей задачи - не меньше пяти. Т.к. анализируется информация про примерно миллион человек, сделать в кубе 5 измерений "Категория" не представляется возможным - в таблице фактов получится 1000000 5 записей для каждой загрузки.
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565730
Константин Лисянский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL использовать не пробовали?
Задача тривиальная. SQL напишет и первоклассник.
Можете навесить Microstrategy - получите тот же SQL, только визуально построенный. И не придётся отдельные измерения городить для разных категорий.


С уважением,
Константин Лисянский
http://lissianski.narod.ru
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565747
Фотография Old Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот в этом месте поподробнее, пожалуйста.
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565767
Andronov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я не совсем понял, какой SQL имелся ввиду.
Кроме того, что надо народ считать по категориям, нужно это же число людей анализировать еще по куче всяких критериев. Как оптимальный вариант было решено построить куб и отдать для анализа пользователям. Конечно можно написать полсотни статических отчетов с кучей параметров, но это долго, дорого и неудобно.

С Microstrategy никогда не работал, поэтому не могу оценить, насколько все это реализуемо. Если есть не слишком большое описание - буду очень благодарен за ссылку на него.
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565805
Фотография Гликоген
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а число категорий фиксировано? или хотя бы прогноз их числа на обозримое время есть?
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32565824
Andronov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Категории могут добавляться, но можно с уверенностью сказать, что их число не станет в ближайшие года три превышать 300.
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32566190
Константин Лисянский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Old NickА вот в этом месте поподробнее, пожалуйста.

Ну, на самом деле это - классическая задача анализа потребительской корзины в розничной торговле. Или, в общем виде, "анализ ассоциаций".
В общем виде задача сложнее и решают её продукты класса data mining. Это поиск двух (или более) категорий, которые часто встречаются вместе. В таком виде ни OLAP, ни SQL эту задачу запросто не решит.
Однако, если мы ищем только пары, и обе категории в паре нам известны, то не кажется ли вам, что задача решается, действительно просто? Ведь всё известно, надо только сосчитать.

Для примера приведу отчёт, который я сделал на Microstrategy на примере tutorial-проекта, который входит в инсталляцию.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
                                      Customer Count	Referenced Item Customer Count
The Art of Bev Doolittle	 74 	              8 
Art As Experience		 61 	              9 
The Painted Word		 51 	              4 
Hirschfeld on Line		 43 	              2 
Adirondack Style		 42 	              6 
Architecture : Form, Space	 42 	              4 

В первом столбце - названия продуктов, во втором - количество клиентов, купивших эти продукты, в третьем - количество клиентов, которые при этом купили ещё один продукт, который я задал в качестве параметра отчёта.
При запуске отчёта мне предлагается выбрать этот продукт.

Вот SQL, который при этом генерируется (база на MS Access):

Код: 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.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
Report: New Report
Data Rows:  352 
Data Columns:  2 
Cache Used: No

Execution Start Time:		 06 / 17 / 2004   19 : 04 : 19 
Execution Finish Time:		 06 / 17 / 2004   19 : 04 : 41 

Total Duration:		 0 : 00 : 22 . 62 
SQL Duration:		 0 : 00 : 22 . 61 
Analytical Duration:		 0 : 00 : 00 . 00 
Other Processing Duration:		 0 : 00 : 00 . 01 

Number of Rows Returned:		 352 
Number of Columns Returned:		 5 
Number of Temp Tables:		 6 

Total Number of Passes:		 19 
Number of SQL Passes:		 19 
Number of Analytical Passes:		 0 

DB User:		Data
DB Instance:		Tutorial Data

Tables Accessed:
LU_CUSTOMER	
LU_ITEM	
LU_ORDER	
ORDER_DETAIL	


SQL Statements:

Pass0 - Duration:  0 : 00 : 00 . 02 
create table ZZTA700GKJ7SP000 (
 ITEM_ID SHORT, 
 WJXBFS1 LONG)


Pass1 - Duration:  0 : 00 : 09 . 96 
insert into ZZTA700GKJ7SP000 
select a12.[ITEM_ID] AS ITEM_ID,
	count(a11.[CUSTOMER_ID]) AS WJXBFS1
from [LU_CUSTOMER] a11, 
	[LU_ITEM] a12
group by a12.[ITEM_ID]

Pass2 - Duration:  0 : 00 : 00 . 00 
create table ZZTA700GKJ7OT001 (
 ITEM_ID SHORT, 
 WJXBFS1 SHORT)


Pass3 - Duration:  0 : 00 : 08 . 33 
insert into ZZTA700GKJ7OT001 
select distinct a11.[ITEM_ID] AS ITEM_ID,
	a12.[CUSTOMER_ID] AS WJXBFS1
from [ORDER_DETAIL] a11, 
	[LU_ORDER] a12
where a11.[ORDER_ID] = a12.[ORDER_ID]

Pass4 - Duration:  0 : 00 : 00 . 02 
create table ZZTA700GKJ7SP002 (
 ITEM_ID SHORT, 
 WJXBFS1 LONG)


Pass5 - Duration:  0 : 00 : 00 . 90 
insert into ZZTA700GKJ7SP002 
select pa2.[ITEM_ID] AS ITEM_ID,
	count(*) AS WJXBFS1
from [ZZTA700GKJ7OT001] pa2
group by pa2.[ITEM_ID]

Pass6 - Duration:  0 : 00 : 00 . 00 
create table ZZTA700GKJ7MD003 (
 ITEM_ID SHORT, 
 WJXBFS1 LONG, 
 WJXBFS2 LONG)


Pass7 - Duration:  0 : 00 : 00 . 00 
insert into ZZTA700GKJ7MD003 
select pa1.[ITEM_ID] AS ITEM_ID,
	pa1.[WJXBFS1] AS WJXBFS1,
	pa3.[WJXBFS1] AS WJXBFS2
from [ZZTA700GKJ7SP000] pa1, 
	[ZZTA700GKJ7SP002] pa3
where pa1.[ITEM_ID] = pa3.[ITEM_ID]

Pass8 - Duration:  0 : 00 : 00 . 00 
create table ZZTA700GKJ7OT004 (
 ITEM_ID SHORT, 
 WJXBFS1 SHORT)


Pass9 - Duration:  0 : 00 : 03 . 19 
insert into ZZTA700GKJ7OT004 
select distinct a11.[ITEM_ID] AS ITEM_ID,
	a12.[CUSTOMER_ID] AS WJXBFS1
from [ORDER_DETAIL] a11, 
	[LU_ORDER] a12
where a11.[ORDER_ID] = a12.[ORDER_ID]
 and	((a12.[CUSTOMER_ID])
 in	(select r12.[CUSTOMER_ID]
	from [ORDER_DETAIL] r11, 
		[LU_ORDER] r12
	where r11.[ORDER_ID] = r12.[ORDER_ID]
	 and	r11.[ITEM_ID] in ( 119 )))

Pass10 - Duration:  0 : 00 : 00 . 01 
create table ZZTA700GKJ7MD005 (
 ITEM_ID SHORT, 
 WJXBFS1 LONG)


Pass11 - Duration:  0 : 00 : 00 . 08 
insert into ZZTA700GKJ7MD005 
select pa5.[ITEM_ID] AS ITEM_ID,
	count(*) AS WJXBFS1
from [ZZTA700GKJ7OT004] pa5
group by pa5.[ITEM_ID]

Pass12 - Duration:  0 : 00 : 00 . 02 
select pa4.[ITEM_ID] AS ITEM_ID,
	a11.[ITEM_NAME] AS ITEM_NAME,
	pa4.[WJXBFS1] AS WJXBFS1,
	pa4.[WJXBFS2] AS WJXBFS2,
	pa6.[WJXBFS1] AS WJXBFS3
from [ZZTA700GKJ7MD003] pa4, 
	[ZZTA700GKJ7MD005] pa6, 
	[LU_ITEM] a11
where pa4.[ITEM_ID] = pa6.[ITEM_ID] and 
	pa4.[ITEM_ID] = a11.[ITEM_ID]

Pass13 - Duration:  0 : 00 : 00 . 03 
drop table ZZTA700GKJ7SP000

Pass14 - Duration:  0 : 00 : 00 . 00 
drop table ZZTA700GKJ7OT001

Pass15 - Duration:  0 : 00 : 00 . 02 
drop table ZZTA700GKJ7SP002

Pass16 - Duration:  0 : 00 : 00 . 00 
drop table ZZTA700GKJ7MD003

Pass17 - Duration:  0 : 00 : 00 . 02 
drop table ZZTA700GKJ7OT004

Pass18 - Duration:  0 : 00 : 00 . 00 
drop table ZZTA700GKJ7MD005


Вот и всё - ничего сложного. Отчёт делается за 3 минуты.
Если надо ещё какие-то критерии добавить в отчёт - тоже не проблема. Microstrtategy - довольно мощный инструмент. А реляционные СУБД в задачах на Distinct Count не уступают MOLAP-серверам (как мы уже выяснили в результате дискуссии с Владимиром Ивановым в этом форуме).


С уважением,
Константин Лисянский
http://lissianski.narod.ru
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32566344
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Константин Лисянский А реляционные СУБД в задачах на Distinct Count не уступают MOLAP-серверам (как мы уже выяснили в результате дискуссии с Владимиром Ивановым в этом форуме).

Я бы даже сказал что хорошо превосхдят. (пока)
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32566586
Jurii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Andronov:

Еще лучше было бы иметь возможность спрашивать примерно так:
Сколько у нас слесарей? - 2
А сколько из них кассиров? - 1


Хотя такую задачудействительно очень удобно решать с помощью продуктов Query & Reporting (Cognos Impromptu/ReportNet, Microstrategy, BO и т.п.), я могу Вас понять - поскольку хочется получить не только статичный отчет, но и возможность интерактивного анализа с высокой скоростью.

Поэтому пока могу предложить такой вариант:
Выводите в OLAP-отчете в строки всех людей
В столбец сначала выводите категорию Слесарей - и в колонке будут либо нули, либо единички, и внизу - общий итог (сколько всего слесарей.
Далее выводите вторую колонку - студенты. И далее перемножаете в OLAP-клиенте эти колонки друг на друга. В итоге если у человека единичка и по слесарю, и по студенту - получится единичка, если либо по слесарю либо по студенту - ноль - тогда в итоге будет ноль.
Понятен подход?

P.S. При миллионе строк в OLAP-отчете (если у вас миллион людей) не каждый OLAP-клиент это потянет. Cognos PowerPlay User я тестировал на миллионе строк и тысяче столбцов в отчете...
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32571293
Задачи Distinct Count бывают разные и некоторые из них в AS2K действительно не решаются. Те которые решаются если модель построена проавильно может превосходить реляционные базы на несколько порядков, но почти всегда имеют производительность хуже чем обычное суммирование. В следующей версии имеется имплеметнация many-to-many измерения, которое предназначена точно для сформулированной вами задачи.
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32571381
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр БергерВ следующей версии имеется имплеметнация many-to-many измерения, которое предназначена точно для сформулированной вами задачи.

Ну вот, пошло о будущей версии в настоящем времени и без ссылки на открытые источники - вызовет ли ваш пост неодобрямс ваших коллег с MSFT?
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32571546
LordOfSilence
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 backfire
Ссылка была в соседней ветке :-) Последний постинг. ;-)
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32571560
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LordOfSilence2 backfire
Ссылка была в соседней ветке :-) Последний постинг. ;-)

Да я все видел :-))))))
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32572695
Quant_2004
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я это решил, с помощью mdx выражения такого вида:
count(filter(nonemptyCrossJoin(Descendants([тттт].CurrentMember,[тттт].[dddd])),[Measures].[Колво]>1))

Спускаемся до объекта сравнения, проверяем сколько имеет значений, и подсчитываем их кол-во
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32573821
Фотография Old Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Jurii

И как это работает на миллионе строк? У меня похожая ситуация. Клиент группирует миллион строк быстро, а вот вытаскивается на клиента этот миллион довольно медленно
...
Рейтинг: 0 / 0
Интересная задача при связи "многие-ко-многим"
    #32574548
Quant_2004
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В пределах 3-7 минут.. В зависимости от мощности компьютера клиента. Главное не делать такой выборки по всему кубу, а ограничивать несколькимим значениями в измерениях...
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Интересная задача при связи "многие-ко-многим"
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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