Вопрос

Что ж, как вы можете знать, вы не можете индексировать вид с Self Injoin. Ну, на самом деле даже два присоединения того же стола, даже если это не технически самостоятельно присоединиться. Пара парней из Microsoft придумала оборота. Но это так сложно, я не понимаю это !!!

Решение проблемы входит здесь: http://jmkehayias.blogspot.com/2008/12/Creating-indexed-view-with-sels-soin.html.

Вид, который я хочу применить эту работу вокруг:

create VIEW vw_lookup_test
WITH SCHEMABINDING
AS
select
count_big(*) as [count_all],
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm [owner],
t.circt_cstdn_nm [tech],
dvc.circt_nm,
data_orgtn_yr 
from 
((dbo.dvc 
join dbo.circt 
on dvc.circt_nm = circt.circt_nm) 
join dbo.circt_cstdn o
on circt.circt_cstdn_user_id = o.circt_cstdn_user_id)
join dbo.circt_cstdn t
on dvc.circt_cstdn_user_id = t.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm,
t.circt_cstdn_nm,
dvc.circt_nm,
data_orgtn_yr 
go

Любая помощь была бы очень церован !!!

Большое спасибо заранее!

Редактировать: Итак, я обнаружил, что это также будет работать. Обратите внимание, что я присоединяюсь к таблице один раз в первом проиндексированном виде, а второй раз в втором неиндексированном представлении.

alter VIEW vw_lookup_owner_test2
WITH SCHEMABINDING  
AS 
select
count_big(*) as [countAll],
awc_txt,
city_nm,
str_nm,
stru_no,
dvc.circt_nm,
circt_cstdn_nm,
data_orgtn_yr,
dvc.circt_cstdn_user_id
from dbo.dvc 
join dbo.circt
on dvc.circt_nm = circt.circt_nm
join dbo.circt_cstdn o
on circt.circt_cstdn_user_id = o.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
dvc.circt_nm,
circt_cstdn_nm,
data_orgtn_yr,
dvc.circt_cstdn_user_id
go

и

CREATE UNIQUE CLUSTERED INDEX [idx_vw_lookup_owner2_test1] ON [dbo].[vw_lookup_owner_test2] 
(
    [awc_txt] ASC,
    [city_nm] ASC,
    [str_nm] ASC,
    [stru_no] ASC,
    [circt_nm] ASC,
    [circt_cstdn_nm] ASC,
    [data_orgtn_yr] ASC,
    [circt_cstdn_user_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

и

create view vw_lookup_dvc_loc
as
select
awc_txt,
city_nm,
str_nm,
stru_no,
circt_nm,
o.circt_cstdn_nm as [owner],
--o.circt_cstdn_user_id,
t.circt_cstdn_nm as tech,
data_orgtn_yr
from vw_lookup_owner_test2 o With (NOEXPAND)
join circt_cstdn t
on o.circt_cstdn_user_id = t.circt_cstdn_user_id
group by
awc_txt,
city_nm,
str_nm,
stru_no,
circt_nm,
o.circt_cstdn_nm,
data_orgtn_yr,
t.circt_cstdn_nm
--o.circt_cstdn_user_id

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

Это было полезно?

Решение

Вот что я получил от blogpost

  • Допустим, вы хотите присоединиться к 2 раза на dbo.circt_cstdn, то есть вы хотите что-то вроде

             owner       tech
    rowA     a.nm        b.nm
    ...
    
  • Вместо того, чтобы получить значения в 2 столбца, вы получаете его на 2 строки (2 для каждой строки выше) и добавьте дополнительный столбец, чтобы сказать, какая строка предназначена для какой столбец. Обратите внимание, что строка 1.1 и строка 1.2 имеют те же данные (кроме имени и для столбцов)

             name   for
    row1.1   nm     owner
    row1.2   nm     tech
    ...
    
  • Тогда вы поворачиваете на максимум имени столбец для владельца и техники. ПРИМЕЧАНИЕ. - Максимальная функция - просто чтобы обмануть пивот (которая требует некоторой совокупной функции), вы можете использовать любую совокупную функцию, которая возвращает одинаковое значение, если есть только одна запись владельца Tech Row1 NM NM ...

Теперь, если мы сделаем это для вашего запроса

  1. Создать таблицу D, как этот

     i
     1
     2
    
  2. Крест Присоединяйтесь к первой части вашего запроса с этим

    SELECT 
         count_big(*) as [count_all], 
         awc_txt, 
         city_nm, 
         str_nm, 
         stru_no, 
         dvc.circt_nm, 
         data_orgtn_yr
    FROM  
         dbo.dvc  
         INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm
         CROSS JOIN dbo.d  
    GROUP BY
         awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, d.i
    
  3. Теперь давайте будем использовать ряд для владельца, если di 1, а Tech If Di 2

    SELECT 
         count_big(*) as [count_all], 
         awc_txt, 
         city_nm, 
         str_nm, 
         stru_no, 
         dvc.circt_nm, 
         data_orgtn_yr,
         Case 
             WHEN d.i = 1 THEN 'Owner'
             WHEN d.i = 2 THEN 'Tech'
         END
    FROM  
         dbo.dvc  
         INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm
         CROSS JOIN dbo.d 
    GROUP BY
         awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, 
         Case 
             WHEN d.i = 1 THEN 'Owner'
             WHEN d.i = 2 THEN 'Tech'
         END  
    
  4. Теперь добавьте столбец NM. Чтобы получить имя, которое вы присоединитесь к CIRCT_CSTDN с CIRCT, если это ряд владельца (di = 1), а с dvc, если это технологический ряд (di = 2). ПРИМЕЧАНИЕ - я попробовал здесь ярлык, положив это в состояние соединения. Если это не сработает, попробуйте просмотреть блог Путь (сделайте соединение на CIRCT.CIRCT_CSTDN_USER_ID ИЛИ dvc.circt_cstdn_user_id, а затем используйте предложение, где можно отфильтровать)

    SELECT 
         count_big(*) as [count_all], 
         awc_txt, 
         city_nm, 
         str_nm, 
         stru_no, 
         dvc.circt_nm, 
         data_orgtn_yr,
         Case 
             WHEN d.i = 1 THEN 'Owner'
             WHEN d.i = 2 THEN 'Tech'
         END as PersonType,
         circt_cstdn_nm
    FROM  
         dbo.dvc  
         INNER JOIN dbo.circt on dvc.circt_nm = circt.circt_nm
         CROSS JOIN dbo.d 
         INNER JOIN dbo.circt_cstdn on circt_cstdn_user_id = 
              CASE
                   WHEN d.i = 1 THEN circt.circt_cstdn_user_id
                   WHEN d.i = 2 THEN dvc.circt_cstdn_user_id
              END
    GROUP BY
         awc_txt, city_nm, str_nm, stru_no, dvc.circt_nm, data_orgtn_yr, 
         Case 
             WHEN d.i = 1 THEN 'Owner'
             WHEN d.i = 2 THEN 'Tech'
         END,
         circt_cstdn_nm
    
  5. Создайте представление, используя это и создайте индекс

    create VIEW vw_lookup_test_imed
    WITH SCHEMABINDING 
    AS
        <<query above>>  
    GO
    
    spell to create INDEX
    
  6. Теперь вы поворачиваете, чтобы преобразовать столбец Persontype на владельца и технологии

    SELECT 
         count_all, 
         awc_txt, 
         city_nm, 
         str_nm, 
         stru_no, 
         dvc.circt_nm, 
         data_orgtn_yr,
         [Owner], 
         [Tech] 
    FROM 
    ( 
         SELECT 
              count_all, 
              awc_txt, 
              city_nm, 
              str_nm, 
              stru_no, 
              dvc.circt_nm, 
              data_orgtn_yr,
              PersonType,
              circt_cstdn_nm
         FROM dbo.vw_lookup_test_imed WITH (NOEXPAND) 
    ) src 
    PIVOT 
    ( 
         MAX(circt_cstdn_nm) 
         FOR PersonType IN ([Owner], [Tech]) 
    ) pvt 
    

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

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

Я думаю, что этот синтаксис присоединения ужасен и возник из MS Access. фу. Я рекомендую вам использовать:

select
count_big(*) as [count_all],
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm [owner],
t.circt_cstdn_nm [tech],
dvc.circt_nm,
data_orgtn_yr 

-- HERE
from dbo.dvc
join dbo.circt on (dvc.circt_nm = circt.circt_nm) 
join dbo.circt_cstdn o on (circt.circt_cstdn_user_id = o.circt_cstdn_user_id)
join dbo.circt_cstdn t on (dvc.circt_cstdn_user_id = t.circt_cstdn_user_id)

group by
awc_txt,
city_nm,
str_nm,
stru_no,
o.circt_cstdn_nm,
t.circt_cstdn_nm,
dvc.circt_nm,
data_orgtn_yr 

Этот синтаксис является очистителем, более приемлемым и распознается в SQL Server, Firebird, Oracle, MySQL и многих других. Теперь вы можете увидеть лучшие отношения между «столами». Когда вы присоединяетесь к тому же «таблицу« два или более раз, вам нужно псевдоним каждый. На одной строке «CIRCT_CSTDN» псевдонится как «O». На другой строке «CIRCT_CSTDN» псевдонится как «T».

Я рекомендую использовать левое соединение или внутреннее соединение вместо присоединения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top