Как смоделировать, когда таблица заголовков имеет значения?

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

Таблица заголовка заказа: ordnum, orddate, customerID, Cost_of_packing, Cost_of_delivery

Таблица строк заказа: ordnum, ordlinenum, ProductID, количество, цена.

Столбец Ordnum — это общее поле между двумя вышеуказанными таблицами.

Клиент: идентификатор клиента, имя клиента

Продукт: идентификатор продукта, название продукта.

Как смоделировать эти данные?

Если я объединим таблицы заголовков заказов и строк строк заказа, то есть объединим их в одну таблицу фактов, тогда стоимость упаковки и стоимость доставки будут дублироваться для каждой строки.

Если я сохраню их как две отдельные таблицы фактов, я не смогу соединить их в столбце ordnum, поскольку это нарушает структуру звездообразной схемы. Таким образом, я не могу сообщить заголовок и детали заказа.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Соедините их в одну таблицу и затем используйте DISTINCT(). Такова природа структур заголовок/детализация в звездообразных схемах. Альтернативой является подключение к таблицам фактов, и когда вы соединяете две очень большие таблицы мощности, производительность остальной части модели будет ужасной.

Что вы подразумеваете под connect them into a single table?

variable 19.04.2024 19:40

Объедините таблицу заголовка и сведений в одну большую таблицу. У вас будут повторяющиеся значения для каждой строки заголовка.

davidebacci 19.04.2024 19:49

Хорошо, в этом случае значения стоимости упаковки и стоимости доставки будут дублироваться для каждой позиции детализации заказа. Как предоставить эти значения конечному пользователю? Например, я не могу использовать AVG или MAX, поскольку это даст неверное значение. Я вижу, вы упомянули об использовании DISTINCT. Как именно использовать это для моей цели?

variable 19.04.2024 20:43

Вам нужно будет написать показатели так же, как вы это делаете для продаж. Продажи — это просто SUM ( table[column] ), тогда как поставки будут выглядеть примерно так: SUMX(VALUES(table[ordnum], Cost_of_delivery). Здесь есть очень хорошая статья, в которой объясняется, почему слияние — это правильно, исходя из звездообразной схемы. перспектива sqlbi.com/articles/….

davidebacci 19.04.2024 20:52

Как насчет этого: скажем, я храню заголовок и детали в виде отдельных таблиц фактов. И создайте новую таблицу измерений, содержащую отдельный список OrdNum. И подключите этот дим к обеим таблицам фактов.

variable 19.04.2024 20:58

Кстати, разве ваша приведенная выше формула не должна быть такой: SUMX(VALUES(table[ordnum]), CALCULATE(MAX(cost_of_delivery)))

variable 19.04.2024 21:02

На самом деле, вероятно, это должно быть что-то вроде этого: SUMX(SUMMARIZE('Таблица', 'Таблица'[Заказ], 'Таблица'[Стоимость доставки]), 'Таблица'[Стоимость доставки])

davidebacci 19.04.2024 21:05

Вы можете попробовать создать измерение, но при дальнейшем создании показателей или визуализаций вы, вероятно, столкнетесь с некоторыми дополнительными проблемами. Я обнаружил, что SQLBI обычно является лучшей практикой.

davidebacci 19.04.2024 21:06

какие проблемы вы видите в наличии такого измерения, пожалуйста?

variable 20.04.2024 09:07

Это действительно зависит от вашей модели. Попробуйте создать прототип того, что вы хотите, и если он не работает, вы можете переделать его.

davidebacci 20.04.2024 13:14

Дэвид, на основании чего ты решаешь, должен ли я использовать SUMX(VALUES(table[ordnum]), CALCULATE(MAX(cost_of_delivery))) или SUMX(SUMMARIZE('Table', 'Table'[Order], 'Table'[Delivery Cost]), 'Table'[Delivery Cost]). Я прочитал статью о sqlbi, которой вы поделились, но не понимаю, как писать DAX, когда таблица заголовков/подробностей объединена в одну таблицу.

variable 21.04.2024 01:44

Оба в порядке. Обычно в DAX существует множество способов решения одной и той же проблемы, и проблемы не проявляются, пока вы не протестируете свою конкретную модель. Я бы в первую очередь выбрал первый вариант.

davidebacci 21.04.2024 09:38

Под первым, я полагаю, вы имеете в виду мою версию? Кроме того, не могли бы вы указать мне какие-нибудь статьи о том, как написать такой DAX для обработки таких вещей. Я знаю DAX на среднем уровне, но мне нужно изучить его под этим углом. Пожалуйста, дайте мне несколько советов.

variable 21.04.2024 15:50

Да, ваша версия. Промежуточного DAX должно быть достаточно. Я не знаю конкретных статей, но обычно в SQLBI есть все, что касается DAX. Видео на YouTube для SQLBI также превосходны.

davidebacci 21.04.2024 17:44

Если вы застряли, просто опубликуйте новый вопрос с проблемой

davidebacci 21.04.2024 17:45
Ответ принят как подходящий

Полностью избавьтесь от таблицы заголовков заказов. Перенесите даты заказов и идентификаторы клиентов в таблицу сведений о заказе и распределите затраты по строкам.

Если вам нужно выполнить расчеты на уровне строки, вам придется определить правила распределения затрат. Например, выразите затраты как % от общей стоимости заказа, а затем умножьте на суммы строк. Это сделает затраты полностью аддитивными.

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

Редактировать:

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

Модель данных:

Макет таблицы Orders с номерами верхнего уровня, выделенными для первой строки заказа:

Итоговый отчет выглядит так:

Подробный отчет о заказе с детализацией продуктов:

Меры DAX:

линейный уровень:

Order Qty = SUM(Orders[Qty])

Order Amount = SUMX(Orders, Orders[Price]*Orders[Qty])

верхний уровень:

Order Delivery Cost =
CALCULATE (
    SUM ( Orders[Delivery Cost] ),
    REMOVEFILTERS ( Orders[Product ID] )
)

Комбинированные расчеты верхнего и линейного уровня:

Order Total  = [Order Amount] + [Order Delivery Cost]

Как видите, модель проста, а расчеты интуитивно понятны и производительны. Единственное, что выглядит немного странно, — это пробел в стоимости доставки, но это цена, которую вам придется заплатить за нераспределение.

К сожалению, не существует четкого правила распределения затрат на уровне строки.

variable 20.04.2024 10:53

В этом корень вашей проблемы: номера уровня строки и номера уровня заказа находятся на разном уровне детализации. Решать это приходится так или иначе — либо свертывать номера строкового уровня в верхний уровень, либо распределять вниз. Любое «решение», игнорирующее это несоответствие, скрывает реальную проблему под ковриком. Если у вас нет правила распределения, установите его.

RADO 20.04.2024 16:16

А как насчет того, чтобы сохранить их в отдельных таблицах фактов и создать измерение с отдельным OrdNum. Затем создайте отношение 1:M между этим тусклым изображением и каждой таблицей фактов. Таким образом, пользователь может анализировать заголовок и детали, а также переходить от заголовка к деталям с помощью общего измерения.

variable 20.04.2024 17:59

Проблема с этим дизайном заключается в том, что другие измерения не будут использоваться совместно (продукт, дата, клиент). Это сделает анализ и код DAX очень громоздкими и неэффективными. Кроме того, он по-прежнему не учитывает уровень несоответствия детализации. Например, предположим, что бизнес задает вам вопрос: покажите мне чистую прибыль по продуктам. Как бы вы это сделали? В предложенном вами дизайне вы не сможете отвечать на подобные вопросы.

RADO 20.04.2024 19:15

Если предположить, что нет необходимости показывать профиль сети по продуктам, то является ли это хорошей моделью? Я уверен, что это распространенный сценарий, когда значения уровня заказа не могут быть присвоены уровню детализации. Как разработчики моделей справляются с таким сценарием?

variable 26.04.2024 10:10

Делать порядок измерением — плохая практика. Заказы по сути являются транзакциями, а это означает, что они являются фактами, а не измерениями. На практике размер заказа будет постоянно расти и в конечном итоге станет очень высоким. Схема «Правильное начало» требует, чтобы измерения были короткими и широкими, а таблица фактов — высокой и узкой (высокие размеры снижают производительность запросов). Лучше всего распределять значения уровня заголовка до уровня строки (прочитайте этот технический документ от Кимбалла (файл в формате pdf): kimballgroup.com/wp-content/uploads/2013/08/…

RADO 26.04.2024 10:34

В идеале бизнес должен предоставить вам правильные правила распределения. Если нет, подделайте их. В худшем случае просто присвойте значения заголовка первой строке и null остальным. Чтобы получить стоимость доставки, достаточно просто суммировать (если вы не фильтруете отчет по продукту - если это так, используйте «удалить фильтры» для продукта). Такая модель превосходит описанную вами во всех аспектах.

RADO 26.04.2024 10:42

Как насчет присвоения значений заголовка каждой строке, а затем я использую SUMX(VALUES(table[ordnum]), CALCULATE(MAX(cost_of_delivery))) для значения, поэтому у меня есть одна таблица фактов.

variable 26.04.2024 12:50

Конечно, но почему вы хотите усложнить задачу? Итератор с CALCULATE означает цикл с переходом контекста, что очень дорого. При распределении это просто СУММА (стоимость доставки).

RADO 26.04.2024 14:59

Я просто не могу распределить. В лучшем случае я понимаю вашу точку зрения, что мне нужно разместить все это в одной строке подробностей. Я думаю об этом.

variable 26.04.2024 16:12

если я распределяю все значение заголовка продажи одной из подробных записей, то в чем именно заключается ограничение такой модели?

variable 26.04.2024 16:37

Единственное ограничение — это продукт. Без правильного распределения ваш анализ выручки будет неправильным, если продукты будут фильтроваться. Вы можете решить эту проблему, создав специальный отчет для расчетов выручки или используя REMOVEFILTERS для продукта в показателях, которые включают цифры выручки. . В любом случае, это ничем не отличается от других рассмотренных вами моделей — у них всех одна и та же проблема, плюс для них потребуется запутанный и медленный DAX.

RADO 27.04.2024 03:16

@variable: Я отредактировал свой ответ, чтобы показать вам, как это выглядит на практике.

RADO 27.04.2024 03:54

Спасибо, что нашли время для подробного ответа, внесшего ясность. Таким образом, функция удаления фильтров полезна только в том случае, если показатель используется вместе с продуктом и деталями не верхнего уровня.

variable 27.04.2024 04:12

Да, а также если вы поместите продукт в срез, который фильтрует отчет (поскольку, если продукт выбран, общие затраты будут неверными).

RADO 27.04.2024 04:18

Хорошая работа, RADO – проголосовал за.

davidebacci 27.04.2024 12:03

@rado - когда я выделяю значения уровня заголовка одной из строк сведений, тогда другим строкам должно быть присвоено значение 0 или пустое/нулевое?

variable 27.04.2024 17:53

Либо один хорошо; Я предпочитаю использовать пробелы, потому что отчеты выглядят чище.

RADO 27.04.2024 19:30

Другие вопросы по теме