Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Треугольный LEFT FULL JOIN  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Дано:
DECLARE	@Base TABLE (
	 ID	Int NOT NULL PRIMARY KEY
	,KL	Int NOT NULL UNIQUE
	,KR	Int NOT NULL UNIQUE
)
DECLARE	@Left TABLE (
	 KL	Int	-- REFERENCES @Base (KL)
	,Ver	Int
	,PRIMARY KEY (KL,Ver)
)
DECLARE	@Right TABLE (
	 KR	Int	-- REFERENCES @Base (KR)
	,Ver	Int
	,PRIMARY KEY (KR,Ver)
)
INSERT	@Base  VALUES (1,3,1),(2,4,9)
INSERT	@Left  VALUES (3,1),(3,2),(4,2)
INSERT	@Right VALUES (1,2),(9,1),(9,2)
Получить:
B.IDL.VerR.Ver
11
122
21
222

Вопрос больше касается, как это получить одним обращением к таблице @Base.
Отсутствие механизмов скуля или ошибка мышления?
        [Base]
| |
LEFT LEFT
| |
[Left] - FULL - [Right]
30 мар 11, 19:47    [10448233]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Валдай
Member

Откуда:
Сообщений: 113
Ну, если принципиально однократное обращение именно к @Base :)

select B.ID,  LVER=L.Ver, RVER = R.Ver
from @Base B
cross apply( 
             select Ver from @Left where KL = B.KL
             union 
             select Ver from @Right where KR = B.KR
           ) P           
left join @Left L On B.KL = L.KL and L.Ver=P.Ver
left join @Right R ON b.KR = R.KR and R.Ver = P.Ver
30 мар 11, 20:19    [10448314]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Валдай
Ну, если принципиально однократное обращение именно к @Base :)
Чёрд. Я на своей волне.

Конечно же однократное всех 3х таблиц.
30 мар 11, 20:24    [10448325]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Валдай
Member

Откуда:
Сообщений: 113
Mnior
Конечно же однократное всех 3х таблиц.

Аа.. так интереснее:)

Оно?
select 
  ID = case when R.KR is null then ID else MAX(ID)OVER(PARTITION by R.KR)end,
  LVER=F.Ver,
  --R.KR,
  RVER=R.Ver
from           
(
  select 
    B.ID, 
    B.KR, 
    L.Ver
  from @Base B
  left join @Left L On B.KL = L.KL 
)F
full join @Right R ON F.KR = R.KR and F.Ver = R.Ver           
order by ID,ISNULL(F.Ver,R.Ver)
30 мар 11, 20:53    [10448390]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Mnior
Конечно же однократное всех 3х таблиц.
А откуда такое пространное требование, если не секрет?
30 мар 11, 23:14    [10448795]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Валдай
Оно?
Проверить пока не могу.
case when R.KR is null then ID else MAX(ID)OVER(PARTITION by R.KR) end
Боже.
INSERT	@Base  VALUES (1,3,1),(2,4,5),(3,7,9)
INSERT	@Left  VALUES (3,1),(3,2),(4,2),(7,1)
INSERT	@Right VALUES (1,2),(5,1),(5,2),(9,2)


И зачем у вас под-запрос?
FROM	          @Base  B
	LEFT JOIN @Left  L ON B.KL  = L.KL 
	FULL JOIN @Right R ON R.KR  = B.KR
			  AND R.Ver = L.Ver

Если я не ошибаюсь, это (сам запрос) скорее риторический вопрос.
Меня больше интересует другой:
Mnior
Отсутствие механизмов скуля или ошибка мышления?
Неужели все возможности сходятся к Звязде? Или это неправильно математически (по реляционной алгебре)?

О, чйорд побъери, вспомнил старый вопрос, который возможно даже на этом форуме и задавал. Несколько несвязанных проблем и все сходятся к одной.
Кароче, всё-таки FULL JOIN не полно-функционален.
Нужен MERGE вместо INSERT / UPDATE / DELETE
Нужен MERGE JOIN вместо INNER / LEFT / FULL.
FROM	          @Base  B
	LEFT  JOIN @Left  L      ON B.KL  = L.KL 
	MERGE JOIN @Right R LEFT ON R.KR  = B.KR
			    FULL ON R.Ver = L.Ver


Если серьёзнее, то нужно FULL расширить до 2х этапного, по некоторым колонкам LEFT по остальным FULL. И возможно не по колонкам, а по алиасам.
Если посмотреть ещё на одну проблему, то при FULL неудобно с ключём (связки) возиться - IsNull убого как-то. Всё-таки у самой связки неплохо также иметь алиас.

FROM	          @Base  B
	LEFT JOIN @Left  L ON B.KL  = L.KL 
	FULL JOIN @Right R ON [ AS JoinAlias ]
			      R.KR  = B.KR  [ AS JoinColumnAlias ] [ BY LEFT ]
			      R.Ver = L.Ver [ AS JoinColumnAlias ] [ BY FULL ]
Изобретаю ласапед?

Гавриленко Сергей Алексеевич
А откуда такое пространное требование, если не секрет?
Вы про одно обращение?
Да нет, это больше теория. На практике лишнее обращение не проблема - сервер он железный, всё стерпит.
Просто частенько приходится писать похожие запросы - банально неудобно и неэффективно.

Связанный топик.
31 мар 11, 00:03    [10448941]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
qwrqwr
Member

Откуда: Msk
Сообщений: 1684
Mnior
Конечно же однократное всех 3х таблиц.

Может так?
DECLARE	@Base TABLE (
	 ID	Int NOT NULL PRIMARY KEY
	,KL	Int NOT NULL UNIQUE
	,KR	Int NOT NULL UNIQUE
)
DECLARE	@Left TABLE (
	 KL	Int	-- REFERENCES @Base (KL)
	,Ver	Int
	,PRIMARY KEY (KL,Ver)
)
DECLARE	@Right TABLE (
	 KR	Int	-- REFERENCES @Base (KR)
	,Ver	Int
	,PRIMARY KEY (KR,Ver)
)
INSERT	@Base  VALUES (1,3,1),(2,4,5),(3,7,9)
INSERT	@Left  VALUES (3,1),(3,2),(4,2),(7,1)
INSERT	@Right VALUES (1,2),(5,1),(5,2),(9,2)

select ID, KL, KR 
  from (select ID, f, Ver, Ver v2
          from (select * from @Base unpivot(v for f in(KL,KR))U) Q1
          left join
               (select *,'KL'x from @Left union all select *,'KR' from @Right) Q2
            on Q1.v=Q2.KL and Q1.f=Q2.x
       ) Q3 pivot(Max(v2) for f in(KL,KR))P
 order by 1

/*
ID          KL          KR
----------- ----------- -----------
1           1           NULL
1           2           2
2           NULL        1
2           2           2
3           1           NULL
3           NULL        2
*/
31 мар 11, 11:14    [10450019]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Валдай
Member

Откуда:
Сообщений: 113
Mnior
Валдай
Оно?
Проверить пока не могу.
case when R.KR is null then ID else MAX(ID)OVER(PARTITION by R.KR) end
Боже.
INSERT	@Base  VALUES (1,3,1),(2,4,5),(3,7,9)
INSERT	@Left  VALUES (3,1),(3,2),(4,2),(7,1)
INSERT	@Right VALUES (1,2),(5,1),(5,2),(9,2)

поправка
select *
from  
(           
  select 
    ID = case when R.KR is null then ID else MAX(ID)OVER(PARTITION by R.KR)end,
    LVER=F.Ver, RVER=R.Ver
  from           
  (
    select B.ID, B.KR, L.Ver
    from @Base B left join @Left L On B.KL = L.KL 
  )F
  full join @Right R ON F.KR = R.KR and F.Ver = R.Ver 
)F
where ID IS NOT NULL          
order by ID,ISNULL(LVER,RVER)

Mnior
И зачем у вас под-запрос?


Для читабельности.
31 мар 11, 12:20    [10450564]     Ответить | Цитировать Сообщить модератору
 Re: Треугольный LEFT FULL JOIN  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Валдай
поправка
Неудачная.
Посмотрите результат у qwrqwr.
IDKLKR
11
122
21
222
31
32
Последней строки нехватает.
Валдай
Mnior
И зачем у вас под-запрос?
Для читабельности.
Ёе становится меньше.
Кстати, qwrqwr:
FROM (select * from @Base unpivot(v for f in(KL,KR))U) Q1
FROM @Base unpivot(v for f in(KL,KR)) Q1
Для pivot/unpivot иногда нужно только вышестоящую консрукцию завернуть в подзапрос, для уменьшения количества колонок. Более того это надо делать, т.к. количество колонок у таблицы может увеличиться.

qwrqwr, представте что:
  • ключи KL и KR разнотипные и много колоночные
  • в таблицах есть данные, а не только ключи
    Так что за умения 5, за вопрос - OffTop.

    Так что вопрос остаётся открытый. Боюсь что вечно. Но это (расширенный FULL JOIN и расширенный MERGE) я бы хотел чтоб появилось.
  • 1 апр 11, 09:49    [10455212]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    iljy
    Member

    Откуда:
    Сообщений: 8711
    Mnior
    qwrqwr, представте что:
  • ключи KL и KR разнотипные и много колоночные
  • в таблицах есть данные, а не только ключи
    Так что за умения 5, за вопрос - OffTop.

  • А если так?
    DECLARE	@Base TABLE (
    	 ID	Int NOT NULL PRIMARY KEY
    	,KL	Int NOT NULL UNIQUE
    	,KR	Int NOT NULL UNIQUE
    )
    DECLARE	@Left TABLE (
    	 KL	Int	-- REFERENCES @Base (KL)
    	,Ver	Int
    	,PRIMARY KEY (KL,Ver)
    )
    DECLARE	@Right TABLE (
    	 KR	Int	-- REFERENCES @Base (KR)
    	,Ver	Int
    	,PRIMARY KEY (KR,Ver)
    )
    INSERT	@Base  VALUES (1,3,1),(2,4,9),(3,5,7)
    INSERT	@Left  VALUES (3,1),(3,2),(3,3),(4,2),(5,2)
    INSERT	@Right VALUES (1,2),(9,1),(9,2),(7,1)
    
    
    select b.id, MAX(l.ver) KL, MAX(r.Ver)KR
    from @Base b  cross apply( select 'R' union all select 'L') t(t)
       left join @Left l on b.KL = l.KL and t = 'L'
       left join @Right r on b.KR = r.KR and t = 'R'
    group by b.ID, ISNULL(r.Ver, l.Ver)
    having ISNULL(r.Ver, l.Ver) is not null -- На всякий случай, а то получается фигня при висячем левом или правом ключе
    order by b.ID, ISNULL(r.Ver, l.Ver)
    Колонок может быть сколько угодно, данные тоже не потеряются - добавить их в group by и будет счастье. Не знаю насчет оптимальности, надо смотреть на большом количестве данных.
    26 май 11, 20:49    [10715991]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    iljy
    select b.id, MAX(l.ver) KL, MAX(r.Ver)KR
    from @Base b  cross join( select 'R' union all select 'L') t(t)
       left join @Left l on b.KL = l.KL and t = 'L'
       left join @Right r on b.KR = r.KR and t = 'R'
    group by b.ID, ISNULL(r.Ver, l.Ver)
    order by b.ID, ISNULL(r.Ver, l.Ver)
    Оттолкнулись от первого варианта (Валдай).
    А дальше, когда добавим поля данных? Max? А если XML, Bit?
    Всё ужасно неудобно и тормозит.
    Вот получше (по планам):
    select b.id, t.Ver, Max(t.LK), Max(t.RK)
    from @Base b  cross apply(
    	SELECT Ver,KL,NULL,Data,NULL	FROM @Left  l where l.KL = b.KL
    union all
    	SELECT Ver,NULL,KR,NULL,Data	FROM @Right r where r.KR = b.KR
    ) t (Ver,LK,RK,LData,RData)
    group by b.ID, t.Ver
    order by b.ID, t.Ver
    Ну это так поиграться. Всё равно явно видно ограничения языка и реализации.
    В последний плане нужно merge-ить последние два оператора Join+Group чтобы получилось эффективно. Как это сделали с (Anit)SemiJoin.

    Как я уже упоминал, тогда можно сделать человеческий MERGE.
    27 май 11, 13:41    [10719417]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    iljy
    Member

    Откуда:
    Сообщений: 8711
    Mnior
    Оттолкнулись от первого варианта (Валдай).

    Нет, скорее qwrqwr.
    Mnior
    А дальше, когда добавим поля данных? Max? А если XML, Bit?
    Всё ужасно неудобно и тормозит.
    Вот получше (по планам):
    select b.id, t.Ver, Max(t.LK), Max(t.RK)
    from @Base b  cross apply(
    	SELECT Ver,KL,NULL,Data,NULL	FROM @Left  l where l.KL = b.KL
    union all
    	SELECT Ver,NULL,KR,NULL,Data	FROM @Right r where r.KR = b.KR
    ) t (Ver,LK,RK,LData,RData)
    group by b.ID, t.Ver
    order by b.ID, t.Ver
    Ну это так поиграться. Всё равно явно видно ограничения языка и реализации.
    В последний плане нужно merge-ить последние два оператора Join+Group чтобы получилось эффективно. Как это сделали с (Anit)SemiJoin.

    Можно еще так.
    select b.id, t.Ver, t.LK, t.RK
    from @Base b  cross apply(
    	SELECT isnull(r.Ver,l.Ver) Ver,l.KL,r.KR
    	FROM 
    		(select * from @Left l where l.KL = b.KL) l
    			 full join
    		(select * from @Right r where r.KR = b.KR) r on l.Ver = r.Ver
    ) t (Ver,LK,RK)
    Просто тут начинаются проблемы с математикой. Реляционная алгебра строится на бинарных операциях, а вы предлагаете фактически тернарную. Ну или очень сложную логику соединения.

    Mnior
    Как я уже упоминал, тогда можно сделать человеческий MERGE.
    То же самое.
    27 май 11, 21:14    [10722979]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    iljy
    Просто тут начинаются проблемы с математикой. Реляционная алгебра строится на бинарных операциях, а вы предлагаете фактически тернарную. Ну или очень сложную логику соединения.
    С математикой (реляционным исчислением) тут как я понимаю всё замечательно. Все три отношения между каждым из кортежей объектов как вы их там назвали - бинарные.
    И вспоминаем тёплые ламповые операторы *=, =* и *=*.
    Проблема именно в языке и отсутствии нормальной реализации.

    Например для отношений соединений нет необходимого алиаса, что требуется (по теории). Это я интуитивно показал здесь: 10448941
    Оно и понятно, на практике оказывается что ассоциативность неудобна сама по себе. Во FROM пишутся целый набор (alias именованных) объектов, а не тупо два. Для INNER JOIN именовать каждое соединение мало практично. А вот на FULL-е мы получаем первую бяку - нет алиаса отношения нет доступа к его ключевым элементам - IsNull/Coalesce в зубы.
    Да нет же - у обыкновенного INNER JOIN практически тоже бяка - приходится выбирать (как буриданов осёл) какую из двух (N) сторон записать в SELECT, выбрал не то, оптимизатор тупанул - план левацкий, гипотетически.
    А с алиасом у сервера руки развязаны изначально.

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

    IMXO, мухи отдельно, котлеты отдельно: набор именованных кортежей + набор именованных отношений. Эквивалентность это забота оптимизатора.

    + Но тут в пост врывается UPDATE и всё портит.
    Героическая идея наших праотцов впихнуть невпихуемое и объединить запросы и изменения на единый интерфейс в Простом Языке Запросов для домохозяек достойно уважения. Но сам UPDATE в текущем виде порочен, это понятно.
    А проблема в нелинейности самих отношений, именованные соединения тут не усугубляют. Ведь можно определить правила поведения, например: = -> изменяются обе колонки, *= -> с одной стороны и если есть то и с другой или т.п. (боже, ещё есть Cross, Except, SemiJoin)

    Все мы знаем, что строка не может обновлятся дважды и вспоминаем заклятую функцию Any при неявном группировании.
    И вот тут всплывает ваша тернарность, и явное понимание, что в мире нет бинарности/дуальности. Т.е. есть А есть Б и есть само соединение/результат (С). (Да, да я Адмирал, никто не спорит)
    И теперь на основании данных A, Б и соединения С что-то вычисляем и делаем что-то с Б. Бредятина же.
    Умножение множеств, множественное использование одного объекта (по разными алиасами), обратный порядок применения отношений, множественная интерпретация и возможностей применения - вот всплывающие проблемы прикручивания общих запросов к модификации данных. Язык модификации видимо должен строится на других принципах.

    Варианты модификаций:
  • изменение данных в представленном результате запроса, словно он передаёт линки на ячейки таблицы.
  • манипуляции же INSERT / DELETE (синхронизации) на результирующем наборе должно отражаться на базовые таблицы согласно указанным отношениям.
  • отражение результата запроса на таблицу "второго рода" приводит к необходимости отражения и их изменений.
    Конечно модель должна быть основой системы и планом изменений, но реалии таковы что работает по другому. Описывается отдельно каждый вид изменения словно они не связаны одной моделью, т.е. бизнес логика многократно дублируется. Таковы реалии и довольствуемся что имеем.
    Слава Аллаху, появился убогенький MERGE, который унифицировал изменение на линейном отношении, но без нормального наложения на это условий (других линейных отношений).

    Далее вспоминаем про физически наложенные связи-отношения замест описанные в запросе, которые надо учитывать при любых условиях. CASCADE, который ломает итак сложную декларативную модель. Разные модели параллельноего взаимодействия, транзакции ...

    Теория, язык, реализация, моделирование, стандарты, реалии, кони, люди - всё смешалось.
    Мда, сложновато, но каждый должен в этом участвовать, чтобы всё учесть и выработать оптимальную систему моделирования и понимать как это всё работает и каков смысл каждой детали.
    KO.
  • Давно пора алгебру/исчисление модификации озвучить/сослаться/описать/разработать/исследовать.
    28 май 11, 16:29    [10724782]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    iljy
    Можно еще так.
    SELECT	 B.ID
    	,RF.Ver
    	,RF.LK	-- L.KL
    	,RF.RK	-- R.KR
    FROM	@Base B  CROSS APPLY (
    	SELECT	 IsNull(RR.Ver,RL.Ver)
    		,RL.KL
    		,RR.KR
    	FROM	(SELECT * FROM @Left  L WHERE L.KL = B.KL) RL
    			FULL JOIN
    		(SELECT * FROM @Right R WHERE R.KR = B.KR) RR
    			ON RL.Ver = RR.Ver
    ) RF (Ver,LK,RK)
    Не можно, а нужно именно так - ровно по словам задачи. И явно видно что именование связок (RL, RR, RF) необходимо.

    Кстати очень интересно ведёт себя оптимизатор в зависимости от типов данных:
    DECLARE	@Base TABLE (
    	 ID	Int NOT NULL PRIMARY KEY
    	,KL	Int NOT NULL UNIQUE
    	,KR	Int NOT NULL UNIQUE
    )
    DECLARE	@Left TABLE (
    	 KL	Int	-- REFERENCES @Base (KL)
    	,Ver	Int
    	,PRIMARY KEY (KL,Ver)
    	,Data	XML -- VarChar(50)
    )
    DECLARE	@Right TABLE (
    	 KR	Int	-- REFERENCES @Base (KR)
    	,Ver	Int
    	,PRIMARY KEY (KR,Ver)
    	,Data	XML -- VarChar(50)
    )
    INSERT @Base(ID,KL,KR) VALUES (1,3,1),(2,4,9),(3,5,7)
    INSERT @Left  (KL,Ver) VALUES (3,1),(3,2),(3,3),(4,2),(5,2)
    INSERT @Right (KR,Ver) VALUES (1,2),(9,1),(9,2),(7,1)
    --------------------------------------------------------------------------------
    SELECT	b.*,t.LData,t.RData
    FROM	@Base b CROSS APPLY (
    	SELECT	IsNull(r.Ver,l.Ver) Ver,l.KL,r.KR,l.Data,r.Data
    	FROM 	(SELECT * FROM @Left  l WHERE l.KL = b.KL) l
    		FULL JOIN	-- FULL MERGE JOIN
    		(SELECT * FROM @Right r WHERE r.KR = b.KR) r ON l.Ver = r.Ver
    ) t (Ver,LK,RK,LData,RData)
    
    Для XML Hash Join превращается в Concat(Loop LeftJoin, Loop LeftAntiSemiJoin) на TableSpool-ах.
    И непонятно почему тупит оптимизатор, который сам показывает что через MergeJoin лучше по всем параметрам.
    28 май 11, 18:38    [10724946]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    FROM	         (@Base BL JOIN @Left  XL ON XL.KL = BL.KL)
    	FULL JOIN(@Base	BR JOIN @Right XR ON XR.KR = BR.KR) ON XR.Ver = XL.Ver
    							   AND BL.ID  = BR.ID
    
    Вместо BR нельзя прописать BL.
    Если чуть расширить синтаксис и вместо "@Base BR" можно как-то указать линк на "BL":
    FROM	         (@Base B  JOIN @Left  L ON L.KL = B.KL)
    	FULL JOIN( Link(B) JOIN @Right R ON R.KR = B.KR) ON R.Ver = L.Ver
    
    Чтоб можно было делать граф, а не только линейное дерево. (слово Link - не подходит)
    Осталось мелочь - как это всё интерпретировать, т.к. IMXO общий знаменатель не всегда можно вынести за скобки.
    Вот пример:
    FROM	          A LEFT JOIN B		ON B-A
    	FULL JOIN C LEFT JOIN Link(A)	ON A-C
    					ON B-C
    Как бы вы интерпретировали?
    Семантическая ошибка, бессмысленный LEFT перед Link(A) или указанный результат?
    29 май 11, 13:29    [10726853]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    Mnior
    т.к. IMXO общий знаменатель не всегда можно вынести за скобки.
    Правильно, поэтому чтобы не было такого ненужного мозго-дробящего бреда, нужно разрешать писать только с уже вынесенными "за скобки" элементами:
    FROM	@Base B ((JOIN @Left  L ON L.KL = B.KL)
    	FULL JOIN(JOIN @Right R ON R.KR = B.KR) ON R.Ver = L.Ver)
    Или:
    FROM	          @Base  B
    	     JOIN(@Left  L ON L.KL = B.KL
    	FULL JOIN(@Right R ON R.KR = B.KR) ON R.Ver = L.Ver)
    29 май 11, 16:56    [10727335]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    iljy испугался моих бредовых мыслей вслух.
    Может краткое содержание предыдущих серий?
    30 май 11, 20:41    [10734904]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    iljy
    Member

    Откуда:
    Сообщений: 8711
    Mnior
    iljy испугался моих бредовых мыслей вслух.
    Может краткое содержание предыдущих серий?

    Да нет, не испугался, просто я не очень представляю под этим математическую базу. Все-таки в целом операция получатся тернарная, потому как в хитрых условиях присоединения третьей таблицы всегда фигурируют ссылки на обе предыдущие. А между двумя таблицами я плохо представляю применимость такого рода усовершенствований. И не уверен я, что практически такое усложнение логики даст серьезный выигрыш во многих случаях. Так что не знаю, что тут добавить.
    30 май 11, 23:37    [10735508]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    iljy
    Все-таки в целом операция получатся тернарная, потому как в хитрых условиях присоединения третьей таблицы всегда фигурируют ссылки на обе предыдущие.
    Если так рассуждать, то все запросы N арные, где N число JOIN во FROM. Это не говоря что в ON итак можно указать сколько угодно предикатов связки с разными таблами. Скорее всего вы не теми словами выражаетесь.
    Вы основываетесь на том, что перемножение очередного множества проводится только на предыдущем результате. Но в данном случае происходит тоже самое.
    Повторю пример:
    FROM	         (@Base BL JOIN @Left  XL ON XL.KL = BL.KL)
    	FULL JOIN(@Base	BR JOIN @Right XR ON XR.KR = BR.KR) ON XR.Ver = XL.Ver
    							   AND BL.ID  = BR.ID
    Два параллельных умножения (INNER) дают результат X1 и X2, которые потом перемножаются (FULL) и дают X3. Ровно тоже самое и здесь:
    FROM	          @Base  B
    	     JOIN(@Left  L ON L.KL = B.KL
    	FULL JOIN(@Right R ON R.KR = B.KR) ON R.Ver = L.Ver)
    Реляционно-Алгебраически идентично. Какая разница, что X1 и X2 строились до этого на одной и той же таблице и в третьем отношении (FULL) фигурирует нативная эквивалентность? Сами операции не поменялись.

    Не знаю зачем вы прицепились к арности. Смотрите, LEFT / RIGHT / FULL -ов нет в алгебре, это укороченная замена эквивалентным наборам комбинаций из базовых отношений (INNER / UNION / EXCEPT). Поэтому говорить об арности уже бессмысленно - она и так "запачкана" множественностью. Расписать эквивалентность? Согласитесь - банально:
       @Base AND     @Left AND NOT @Right
    OR @Base AND     @Left AND     @Right
    OR @Base AND NOT @Left AND     @Right

    Реляционная алгебра (исчисление) строится на логике предикатов первого порядка, никакой проблемы в этом примере для неё нет.
    Ваш же пример через APPLY с лихвой показывает правомочность данного подхода. Чего же боле?

    iljy
    И не уверен я, что практически такое усложнение логики даст серьезный выигрыш во многих случаях.
    Какое усложнение? Всё как было до этого - ничего и не поменяется, а синтаксис практически не расширяется.
    Выигрыш? Ну сами сравните - PIVOT не поленились, хотя он только часть покрыл, всё равно в реале CASE-ы чаще рулят и по возможности (в отчётах например) и по скорости/эффективности. А так сами посудите синтаксис намного проще и нагляднее - букав банально меньше. Я не говорю что оптимизатору проще обрабатывать линейный вариант, чем это месиво N вложенных подзапросов, учёт элементов видимости, цепочки связей с учётом детерминированности мутаторов (функций (IsNull) , фильтров ...) и т.п.

    SQL набрал некоторый набор удобных предикатов (аля FULL). Вот и стоит вопрос, зачем себя ограничивать? Вон APPLY ввели, понимая что слабоват скуль по мощности. А так можно ещё вводить упрощая конструкции. ([ Semi | Not ] JOIN. Особенно в Semi можно как Top(1) пользоваться, если ORDER указать.) Не настаиваю, усложнять просто так не стоит с бодуна, но обсуждаться обязано.
    + Вот забыл в прошлый раз написать: Цепочки (логика последовательных записей)
    Тут вообще пахать и пахать. Хотя здесь проблема реально за рамки алгебры выходит. Тут нужно что-то кардинально новое, а может мне мерещится. :)
    WITH - появился, Будде поклонился.
    Row_Number() косой, ORDER в Sum() - с бородой.
    Смешанный оператор Group-Scan вообще в анналах это-го форума (еле откопал). Т.е. добавить логический оператор группировки к физическому Scan.
    31 май 11, 03:18    [10735942]     Ответить | Цитировать Сообщить модератору
     Re: Треугольный LEFT FULL JOIN  [new]
    Mnior
    Member

    Откуда: Кишинёв
    Сообщений: 6724
    Mnior
    Все мы знаем, что строка не может обновлятся дважды и вспоминаем заклятую функцию Any при неявном группировании.
    Слава Фугэн Босацу, MERGE расставил всё на места.
    Теперь синтаксис не подразумевает множественности, а семантика явно запрещает.

    Это меня безумно радует, что-то всё таки делается для соответствия языка теории.
    Некоторые проблемы решены: OUTPUT и INSTEAD OF. Спасибо M$!
    Осталось допиливать и не останавливаться на достигнутом.
    2 июн 11, 11:22    [10751051]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить