Объяснение зависимостей строк и столбцов - PullRequest
0 голосов
/ 09 июля 2009

Это простой и распространенный сценарий на работе, и я был бы признателен за некоторую информацию.

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

Как владелец магазина, я мог бы ожидать отчеты в форме:

Customer  Dog  Cat  Rabbit
1         2    3    0
2         0    1    1
3         1    2    0
4         0    0    1

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

Customer  Dog  Cat  Rabbit Goldfish
1         2    3    0      0
2         0    1    1      0
3         1    2    0      0
4         0    0    1      0
5         0    0    0      1

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

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

Customer Pet      Quantity
1        Dog      2
1        Cat      3
1        Rabbit   0
1        Goldfish 0
2        Dog      0
2        Cat      1
2        Rabbit   1
...etc

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

б) Как называется концепция, которую я пытаюсь объяснить клиенту (чтобы помочь с поиском в Google)?

Ответы [ 4 ]

2 голосов
/ 09 июля 2009

Название концепции - кросс-таблица, и ее можно выполнить несколькими способами.

MS Access имеет проприетарные расширения для SQL, чтобы это произошло. В SQL pre-2k5 есть трюк CASE, а в 2k5 и позже - PIVOT, но я думаю, что вам все равно нужно знать, какими будут столбцы.

1 голос
/ 10 июля 2009

Я всегда называл это разворотом, но это может быть и не формальное имя.

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

SELECT customer, count(*), sum(CASE WHEN pet='dog' THEN 1 ELSE 0 END) as dog, sum(case WHEN pet='cat' THEN 1 ELSE 0 END) as cast FROM customers join pets

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

1 голос
/ 09 июля 2009

Эта концепция называется pivoting

SQL предполагает, что ваши данные представлены в виде отношений с фиксированной структурой.

Например, равенство - это бинарное отношение, «у клиента столько домашних животных этого типа» - это троичное отношение и т. Д.

Когда вы видите этот набор результатов:

Customer Pet      Quantity
1        Dog      2
1        Cat      3
1        Rabbit   0
1        Goldfish 0
2        Dog      0
2        Cat      1
2        Rabbit   1

, на самом деле это отношение, определяемое всеми возможными комбинациями домен значений, находящихся в этом отношении.

Как, например, клиент 1 (домен customers id's) имеет ровно 2 (домен positive numbers) домашних животных рода dog (домен pets).

Мы не видим такие строки в наборе результатов:

Customer Pet      Quantity
1        Dog      3
Pete     Wife     0.67

, поскольку первая строка имеет значение false (клиент 1 не имеет 3 элементов dog, но 2), а значения второй строки находятся за пределами своих доменных областей.

SQL парадигма подразумевает, что ваши отношения определяются, когда вы выполняете запрос, и каждая возвращаемая строка полностью определяет отношение.

SQL Server 2005+ может отображать строки в столбцы (это то, что вам нужно), но вы должны знать количество столбцов при разработке запроса (не выполняется).

Как правило, отчеты, которые вы пытаетесь создать, создаются с помощью программного обеспечения для составления отчетов, которое умеет переводить реляционные SQL результирующие наборы в хорошо выглядящие удобочитаемые отчеты.

1 голос
/ 09 июля 2009

Некоторые базы данных действительно поддерживают некоторый способ создания кросс-таблиц, но я думаю, что большинству нужно знать столбцы заранее, так что вам придется изменить SQL (и получить базу данных, которая поддерживает такое расширение).

Другой альтернативой является создание программы, которая постобработает вторую "простую" таблицу, чтобы ваши клиенты получили кросс-таблицу в качестве вывода. Вероятно, это проще и более универсально, чем модифицировать SQL или генерировать его динамически.

И о способе объяснения проблемы ... вы можете показать им в Excel, сколько шагов необходимо для получения желаемого результата:

  • Исходные данные (ваш второй листинг).
  • Выберите значения из столбца домашних животных
  • Поместите каждый найденный тип питомца в новый столбец
  • Количество значений для каждого типа на клиента
  • Заполните значения

и затем скажите, что SQL дает вам только исходные данные, так что, конечно, это больше работы.

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