Ответ на оригинальный вопрос
1. Производительность с таблицей как есть.
Что ж, прежде чем кто-либо сможет оценить этот код с точки зрения производительности, нам нужен оператор создания таблицы, включая индексы.
Высший класс производительности.
Поворот - это функция выражения данных, доступных в строках, в столбцах. Если база данных (таблица), скажем, нормирована на 3NF или 5NF, которая ориентирована на строки, то выполнение столбчатых функций на объектах строк будет медленным. Ничего общего с продуктом. Если вам нужен быстрый доступ к столбцам (для Pivoting или любой другой функции столбцов), вам нужны данные в 6NF. Это также делает SQL-запрос, необходимый для выполнения этой задачи, более простым.
Если разработчик моделей данных подготовил таблицу для поворота (обычно это использование типа хранилища данных; структура факта измерения), то это может быть не правда 6NF, но, по крайней мере, это будет лучше, чем 5NF, и будет проще извлекать сводные значения. Когда я увижу DDL, я смогу определить, что это такое (правда, 6NF; лучше, чем 5NF, но не 6NF). Тогда я могу определить, используете ли вы лучший код, чтобы получить то, что вам нужно.
Это только медленно или «дорого», когда таблица не в 6NF.
На этом этапе из вашего кода он даже не выглядит как Pivot (используя стандартное значение термина), он выглядит как MAX()
различных значений (вызывая результирующий столбец Pivotx
не делает его опорным); и вы читаете каждую строку, один раз. То есть у вас процедурное мышление, а не поворотное или ориентированное на множество мышление. Поэтому код, скорее всего, не получит требуемые значения (независимо от того, хорошо он работает или нет, это отдельная проблема).
Использование вами GROUP BY
подтверждает процедурный подход к непроцедурному набору, и это будет медленно (создает рабочие таблицы; оно будет огромным, если ваши данные огромны), и ту же информацию можно получить много быстрее через Размеры. Почему вы не используете таблицы измерений для этой сводной таблицы? Разместите либо DDL для всех таблиц измерений, связанных с этой таблицей, либо для модели данных.
Ответ на комментарий
Я пытаюсь вам помочь, но есть два препятствия. Во-первых, 19 дней между взаимодействиями. Во-вторых, ваш опубликованный SQL не будет работать: для каждой строки он возвращает одинаковые ColValue
в 11 столбцах; Я не могу понять цель вашего использования MAX()
. Хорошо, MAX()
требуется, чтобы превзойти GROUP BY
в подчинении. Поэтому я все еще в растерянности относительно того, что вы намереваетесь (не то, что вы кодировали). Запутывание достаточно справедливо, но здесь мы потеряли смысл.
Да, есть более быстрые способы, но мне нужно понять намерение и родительские таблицы (например, есть ли у вас таблица, в которой (Col1, Col2)
уникальна? Если это база данных, то таблицы не стоят отдельно, они связаны, и отношения имеют какую-то цель. Я понимаю, что вы не думаете , что они актуальны, но это ограничение привело к тому, что вы разместили код; .
В любом случае, чтобы избежать дальнейших задержек, попробуйте этот код. Это всего лишь предположение, мне не кажется правильным, потому что (Col1, Col2, TypeId)
является уникальным; поэтому для каждой строки результата Col1, Col2
будет только один набор TypeId
(заголовок столбца в наборе результатов):
<code>[Superceded, refer below]
И, возможно, вы можете дать мне отзыв об этом.
Ответ на обновленный вопрос
Хорошо, теперь у нас есть один ненормализованный стол. Новый набор шагов. Это построенный набор результатов, использующий коррелированные подзапросы, которые возвращают скаляры. Это не перестановка строк против столбцов; это не стандартный кронштейне (поэтому код, предоставленный не является стержнем). Смертельно просто. Возможно, вы захотите изменить заголовок вопроса, потому что люди ищут настоящий Pivot. И да, это будет работать намного лучше (при условии, что ваш DDL является истинным представлением реальных таблиц).
Для ясности, Pivot (аля MS SQL PIVOT
функция) - это другое животное. Я могу предоставить уродливый и медленный Pivot для ненормализованной базы данных; или чистый, но медленный Pivot из базы данных 5NF; или чистый и быстрый Pivot из базы данных 6NF. Это не так.
Предположим, что это реляционная база данных. Учитывая предоставленный DDL, будет ParentTable, в котором (Col1, Col2)
является уникальным.
Код:
<code>SELECT Col1,
Col2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 1 ) as Latest_1,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 2 ) as Latest_2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 3 ) as Latest_3,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 4 ) as Latest_4,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 5 ) as Latest_5,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 6 ) as Latest_6,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 7 ) as Latest_7,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 8 ) as Latest_8,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 9 ) as Latest_9,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=10 ) as Latest_10,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=11 ) as Latest_11
FROM ParentTable OUTER
Если нет ParentTable (т.е. это не реляционная база данных), создайте его на лету с SELECT-INTO
или используйте производную таблицу:
<code>SELECT Col1,
Col2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 1 ) as Latest_1,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 2 ) as Latest_2,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 3 ) as Latest_3,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 4 ) as Latest_4,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 5 ) as Latest_5,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 6 ) as Latest_6,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 7 ) as Latest_7,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 8 ) as Latest_8,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId= 9 ) as Latest_9,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=10 ) as Latest_10,
( SELECT ColValue FROM RowTable WHERE Col1=OUTER.Col1 AND Col2=OUTER.Col AND TypeId=11 ) as Latest_11
FROM (
SELECT DISTINCT
Col1,
Col2
FROM RowTable
) OUTER
Вы можете избавиться от столбца Id
в RowTable, это 100% избыточный столбец и индекс, который не имеет смысла.