Альтернатива использованию временных таблиц / временных переменных или CTE внутри представления на SQL Server - PullRequest
0 голосов
/ 05 августа 2020

У меня есть сценарий, в котором мне нужно создать представление, которое имеет кучу СОЕДИНЕНИЙ различных операторов выбора.

SELECT DISTINCT ISNULL(ID,'ID') as Id, 
ISNULL(FIRST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
  UNION
SELECT DISTINCT ISNULL(EMP_ID,'ID') as Id, 
ISNULL(LAST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
  UNION
SELECT DISTINCT ISNULL(LICENSE,'ID') as Id, 
ISNULL(COMPANY,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
.
.
.
.
.
10 such selects

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

Create View [test].[emp].[MainView]
AS
select * into #tempTable from [test].[emp].[OrgView]
SELECT DISTINCT ISNULL(ID,'ID') as Id, 
ISNULL(FIRST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable
  UNION
SELECT DISTINCT ISNULL(EMP_ID,'ID') as Id, 
ISNULL(LAST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable
  UNION
SELECT DISTINCT ISNULL(LICENSE,'ID') as Id, 
ISNULL(COMPANY,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable

Невозможно использовать общее табличное выражение (CTE) также с указанным выше запросом, поскольку оно будет доступно только для одного поиска, а не для остальных 9.

Как лучше сделать это на Sql сервере?

Ответы [ 2 ]

1 голос
/ 09 августа 2020

Когда вы используете VIEW, это 1 вызов базы данных независимо от того, что находится внутри представления. Таким образом, нет необходимости использовать временные таблицы или табличные переменные et c. Итак, ваш исходный запрос будет работать нормально внутри VIEW, и это будет один вызов SQL.

CREATE VIEW [test].[emp].[MainView]
AS
SELECT .... FROM [test].[emp].[OrgView]
UNION
SELECT .... FROM [test].[emp].[OrgView]
....

Это эффективность - другое дело, и я не могу комментировать это как полный logi c не попадает в ваши вопросы. Однако, если все предложения JOIN s и WHERE во всех операторах SELECT похожи / совместимы друг с другом, вы можете объединить их с CROSS APPLY, как предлагает @ gordon-linoff, но я вижу, что вы упоминаете один из запросов использует поиск, который не используется другими запросами, поэтому это может быть или невозможно (в вашем сообщении отсутствуют детали).

1 голос
/ 05 августа 2020

Думаю, вы хотите CROSS APPLY вместо UNION. Я немного не понимаю, куда вы хотите поместить лог c, но вот идея:

SELECT DISTINCT v.Id, 
       (COALESCE(FIRST_NAME, 'unknown') + ':' + 'Unknown') AS label,
       COALESCE(VALUE,'unknown') AS [value]
FROM #tempTable CROSS APPLY
     (VALUES (COALESCE(ID, 'ID')),
             (COALESCE(EMP_ID, 'ID')),
             (COALESCE(LICENCE_ID, 'ID')),
             . . .
     ) v(id)

         
...