Как преобразовать строки в столбцы в индексированном представлении? - PullRequest
0 голосов
/ 29 февраля 2012

Я использую OUTER JOIN, чтобы получить значения, хранящиеся в строках, и показать их в виде столбцов. Если значение отсутствует, в столбце отображается NULL.

Исходная таблица:

Id|Name|Value
01|ABCG|,,,,,
01|ZXCB|.....
02|GHJK|;;;;;

Вид:

Id|ABCG|ZXCB|GHJK
01|,,,,|....|NULL
02|NULL|NULL|;;;;

Запрос выглядит так:

SELECT DISTINCT
    b.Id,
    bABCG.Value AS "ABCG"
    bZXCB.Value AS "ZXCB"
    bGHJK.Value AS "GHJK"
FROM
    Bars b
    LEFT JOIN Bars bABCG ON b.Id = bABCG.Id and b.Name = 'ABCG'
    LEFT JOIN Bars bZXCB ON b.Id = bZXCB.Id and b.Name = 'ZXCB'
    LEFT JOIN Bars bGHJK ON b.Id = bGHJK.Id and b.Name = 'GHJK'

Я хочу удалить LEFT JOIN, потому что это не разрешено в индексированном представлении. Я попытался заменить его внутренним SELECT, но внутренний SELECT также не разрешен и UNION тоже. Я не могу использовать INNER JOIN, потому что хочу показать NULL в поле зрения. Что я должен использовать?

Ответы [ 3 ]

2 голосов
/ 29 февраля 2012

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

I верьте , что под покровом это то, что делает SQL Server (в духе, если не в реальной реализации), когда вы создаете индексированное представление.Однако, изучая правила для индексированных представлений, становится ясно, что триггеры должны только использовать таблицы inserted и deleted и не должны требовать сканирования базовых таблиц для выполнения обслуживания - в противном случаедля больших таблиц поддержание этого индексированного представления наложило бы серьезное снижение производительности.

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

Теперь, в вашем конкретном случае, я полагаю для этих триггеров может быть достаточно эффективно выполнять обслуживание, но вам необходимо тщательно рассмотреть все сценарии вставки / обновления / удаления и убедиться, что ваши триггеры действительно точно поддерживают эти данные - например, если вы обновляете какие-либо id s, вам может потребоваться выполнить ряд обновлений, вставок и удалений.

1 голос
/ 29 февраля 2012

Лучшее, что вы сможете сделать, - это использовать внутренние объединения, чтобы получить совпадения, затем объединиться с левыми объединениями и отфильтровать их, чтобы они возвращали только нули.Это, вероятно, не решит вашу проблему.

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

Поскольку вы прокомментировали это для DW, я собираюсь предположить, что ваша система более интенсивна при чтениях, чем при записи, и что данные загружаютсяв это по расписанию процесса ETL.В такой ситуации высокого уровня чтения / низкого уровня записи * я бы порекомендовал вам «материализовать» это представление, что означает, что при запуске процесса ETL генерируется таблица с вашим начальным оператором выбора, который включает левые объединения.Вы примете удар при записи, тогда все ваши чтения будут наравне с производительностью индексированного представления (вы будете делать то же самое, что и индексированное представление, за исключением пакета, а не построчно).Если ваши исходные БД и DW находятся в одном и том же экземпляре, это лучший выбор, чем индексированное представление, поскольку это не повлияет на производительность исходной системы (индексированные представления замедляют вставки).Это та же концепция, что и в индексированном представлении, потому что вы берете удар производительности на вставку, чтобы ускорить выбор.

Я уже шел по этому пути и пришел к следующему выводу:

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

*, когда я сказал «высокое чтение / низкая запись» выше, вы можететакже думайте об этом как "высокая чтение / запись по расписанию"

0 голосов
/ 29 февраля 2012
SELECT DISTINCT
    b.Id,
    (Select bABCG.Value from Bars bABCG where b.Name = 'ABCG')  AS "ABCG"
    ...
FROM
    Bars b

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

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