Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Объединения Union (число прочтений - 4160 )
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Объединения Union
09. Февраля 2009 :: 07:52
Печать  
Помогите пожалуйста победить проблему в запросе: пытаюсь объединить три запроса, работающих по отдельности. Но в третьем запросе нет обного поля, которое есть и обязательно должно присутствовать в первых двух. Подствавлял и null, и ноль, и неопределенные-пустые значения. Все равно пишет ошибку:Meta name parser error: поле таблицы не найдено "$ДокХол.Контрагент"

Сам запрос:
Код
Выбрать все
SELECT ДокХол.IDDOC [Ссылка $Документ.Хустановка]
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
	, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime) ДатаДок
FROM $Документ.Хустановка AS ДокХол
	LEFT OUTER JOIN _1SJOURN AS Журнал ON ДокХол.IDDOC = Журнал.IDDOC
WHERE ((Журнал.CLOSED & 1) = 1)
	AND Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата

UNION ALL

SELECT Хснятие.IDDOC
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
	, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime) ДатаДок
FROM $Документ.Хснятие AS Хснятие
	LEFT OUTER JOIN _1SJOURN AS Журнал ON Хснятие.IDDOC = Журнал.IDDOC
	LEFT OUTER JOIN $Документ.Хустановка AS ДокХол ON $Хснятие.ДокументУ = ДокХол.IDDOC
WHERE (Журнал.ISMARK = 0)
	AND Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата

UNION ALL

SELECT ДокХол.IDDOC
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, Null
	, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime) ДатаДок
FROM $Документ.Хремонт AS ДокХол
	LEFT OUTER JOIN _1SJOURN AS Журнал ON ДокХол.IDDOC = Журнал.IDDOC
WHERE ((Журнал.CLOSED & 1) = 1)
	AND Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата
	AND ($ДокХол.ВидОперации = :ВыбОперация)
 

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #1 - 09. Февраля 2009 :: 08:00
Печать  
Зачем NULL в третьем запросе.
Вместо него надо строку пустого значения из 9 символов.
и количество колонок во всем запросах объедененных union
должно совпадать а у тебя в третьем запросе
нет поля контрагенты.
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #2 - 09. Февраля 2009 :: 08:17
Печать  
Так вот и вопрос: что туда поставить? Пустое значение char(9) ака $ПустойИД ставил. Эффект тот же.
Количество колонок вот не совпадает. Я же писал, что в третьем запросе нет поля "Контрагент". Я его и пытаюсь заменить какой-нибудь пустышкой. А парсер матюкается и замену не приемлет Печаль
Уже подумываю в документ вставить незаполняемый реквизит Контрагент, но это очень некрасиво будет.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #3 - 09. Февраля 2009 :: 08:27
Печать  
Попробуй временно  запрос без третьего запроса.
зачем нужен LEFT OUTER JOIN
по моему нужен INNER JOIN
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #4 - 09. Февраля 2009 :: 08:33
Печать  
Да не JOIN-ах дело. Это пятый вопрос.
А без третьего запроса все работает. И третий запрос сам по себе работает.

Ладно. Упрощаю вопрос.
Есть Таблица 1 с полями А1, Б1, В1. Есть Таблица2 с полями А1, В1.

Пишу:
Код
Выбрать все
Select A1, Б1, В1
From Таблица1

Union All

Select A1, Null, В1
From Таблица2
 



Вот на Null парсер и ругается.

PS Это если абстрагироваться от соединений и левых таблиц.
PPS Сильно не пинайте Улыбка я только разбираться начал недавно.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #5 - 09. Февраля 2009 :: 08:45
Печать  
у меня запрос
Код
Выбрать все
select descr from sc13 where row_id = 1
union all
select NULL from sc13 where row_id = 1 


работает
в joinax тоже и в первую
и с точки зрения производительности и с точки зрения правильности.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #6 - 09. Февраля 2009 :: 08:50
Печать  
(0) Временно убери условие в третьем запросе
AND ($ДокХол.ВидОперации = :ВыбОперация)
может неправильно написал название аттрибута.

Далее поставь опцию Запрос.Отладка(1) и отлаживай
запрос в qa. Так значительно легче разобраться ( ИХМО)
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #7 - 09. Февраля 2009 :: 08:58
Печать  
Убрал все, что можно. Начинаю кипеть.
Запрос из sc13 - это понятно и вопросов вообще не вызывает. Непонятно, за что на меня так сегодня парсер "взъелся" Печаль

Код
Выбрать все
SELECT ДокХол.IDDOC [Ссылка $Документ.Хустановка]
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
FROM $Документ.Хустановка AS ДокХол
UNION ALL

SELECT ДокХол.IDDOC
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, NULL
FROM $Документ.Хремонт AS ДокХол 



ТЗЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
{\\SERVERSQL\WORK\EXTFORMS\ПЕРЕМЕЩЕНИЕ ИМУЩЕСТВА.ERT(76)}: Meta name parser error: поле таблицы не найдено "$ДокХол.Контрагент"
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #8 - 09. Февраля 2009 :: 09:04
Печать  
Код
Выбрать все
SELECT ДокХол.IDDOC [Ссылка $Документ]
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
FROM $Документ.Хустановка AS ДокХол
UNION ALL

SELECT ДокХол.IDDOC
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ПустойИД
FROM $Документ.Хремонт AS ДокХол
 


  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #9 - 09. Февраля 2009 :: 09:12
Печать  
Не взлетел.
Но получилось, когда переписал алиас в последнем присоединяемом запросе.

Код
Выбрать все
SELECT ДокХол.IDDOC [Ссылка $Документ.Хустановка]
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
FROM $Документ.Хустановка AS ДокХол
UNION ALL

SELECT ДокХол1.IDDOC [Ссылка $Документ.Хремонт]
	, $ДокХол1.Холодильник [Холодильник $Справочник.Холодильники]
	, NULL
FROM $Документ.Хремонт AS ДокХол1
 



а просто [Ссылка $Документ] - оно не хочет. нужно еще типизирующее поле.

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

Спасибо за участие Подмигивание
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #10 - 09. Февраля 2009 :: 09:35
Печать  
Код
Выбрать все
SELECT
	 Жур.IDDoc [Док $Документ]
	 ,Жур.IDDocDef Док_вид
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
FROM $Документ.Хустановка AS ДокХол
INNER JOIN _1SJOURN as Жур ON ДокХол.IDDOC =Жур.IDDOC

UNION ALL
SELECT
	 Жур1.IDDoc [Док $Документ]
	 ,Жур1.IDDocDef Док_вид
	, $ДокХол1.Холодильник [Холодильник $Справочник.Холодильники]
	, $ПустойИД
FROM $Документ.Хремонт AS ДокХол1
INNER JOIN _1SJOURN as Жур1 ON ДокХол1.IDDOC =Жур1.IDDOC
  



и еще скажи сколько строк у тебя в таблице _1SJOURN ???
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #11 - 09. Февраля 2009 :: 09:38
Печать  
Ну как вариант. Все равно журнал использовать для сортировки Улыбка
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #12 - 09. Февраля 2009 :: 09:43
Печать  
abjurer писал(а) 09. Февраля 2009 :: 09:38:
Ну как вариант. Все равно журнал использовать для сортировки Улыбка

ничего не понял ???
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #13 - 09. Февраля 2009 :: 09:48
Печать  
все я понял. просто мне впоследствии надо будет сортировать документы по порядку даты. так что журнал использовать в любом случае.
а строк в _1SJOURN у меня 1135712 на текущий момент.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #14 - 09. Февраля 2009 :: 09:50
Печать  
abjurer писал(а) 09. Февраля 2009 :: 09:48:
все я понял. просто мне впоследствии надо будет сортировать документы по порядку даты. так что журнал использовать в любом случае.
а строк в _1SJOURN у меня 1135712 на текущий момент.


тогда разберись почему надо использовать именно INNER JOIN
речь идет о задаче из поста 0.
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #15 - 09. Февраля 2009 :: 10:07
Печать  
Если исходить из того, что все IDDOC из таблицы $Документ.Хустановка являются подмножеством множества значений IDDOC таблицы _1SJOURN, то левое внешнее соединение (LEFT OUTER) будет равнозначно внутреннему (INNER). Если допущение неверно, то значит нарушена целостность базы данных (или как это еще называется, но ситуация в этом случае нештатная).
Или ты имеешь в виду некие внутренние реализации MSSQL, которые быстрее отрабатывают именно внутреннее соединение?
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Объединения Union
Ответ #16 - 09. Февраля 2009 :: 10:17
Печать  
Твой запрос
Код
Выбрать все
SELECT ДокХол.IDDOC [Ссылка $Документ.Хустановка]
	, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
	, $ДокХол.Контрагент [Контрагент $Справочник.Контрагенты]
	, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime) ДатаДок
FROM $Документ.Хустановка AS ДокХол
	LEFT OUTER JOIN _1SJOURN AS Журнал ON ДокХол.IDDOC = Журнал.IDDOC
WHERE ((Журнал.CLOSED & 1) = 1)
	AND Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата
 


Означает ко всем документам Установка надо добавить еще все
проведенные документы по оперативному учету за заданный период.


Также inner join быстрее и с меньшей нагрузкой выполняется
чем left join  т.к.
inner join требует точного совпадения аттрибутов ( как правило аттрибуты это индексы)
когда идет left join надо отобрать сначала все что совпало и добавить все записи из второй таблицы с null полями а это и время
и немалые ресурсы sql сервера.
  
Наверх
 
IP записан
 
abjurer
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 9
Зарегистрирован: 09. Февраля 2009
Re: Объединения Union
Ответ #17 - 09. Февраля 2009 :: 10:23
Печать  
Спасибо за подробности. Приму к сведению. Попытаюсь переделать эстетики ради Улыбка
Но в принципе запрос и с левым соединением отрабатывает за 1-2 секунды. Сервер со скулом как был напряжен на 50-60%, так и остался (43 пользователя сейчас работают)
  
Наверх
 
IP записан
 
Злой Бобр
Junior Member
**
Отсутствует



Сообщений: 56
Местоположение: Украина, Кривой Рог
Зарегистрирован: 07. Марта 2009
Пол: Мужской
Re: Объединения Union
Ответ #18 - 07. Марта 2009 :: 14:24
Печать  
Так невзлетит. Нужно явно добавить справочник и тогда через $ПустойИД. Насчет правильности подхода с LEFT JOIN - учить небуду, сам со временем разберешся что к чему, и почему.
Примерно так:
[code]
(SELECT ДокХол.IDDOC [Ссылка $Документ.Хустановка]
, $ДокХол.Холодильник [Холодильник $Справочник.Холодильники]
Контр.ID [Контрагент $Справочник.Контрагенты]
, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime) ДатаДок
FROM $Документ.Хустановка AS ДокХол
INNER JOIN $Справочник.Контрагенты AS Контр ON $ДокХол.Контрагент=Контр.ID
LEFT OUTER JOIN _1SJOURN AS Журнал ON ДокХол.IDDOC = Журнал.IDDOC
WHERE ((Журнал.CLOSED & 1) = 1)
AND (Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата)
UNION ALL
SELECT Хснятие.IDDOC
, $ДокХол.Холодильник
Контр.ID
, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime)
FROM $Документ.Хснятие AS Хснятие
LEFT OUTER JOIN _1SJOURN AS Журнал ON Хснятие.IDDOC = Журнал.IDDOC
LEFT OUTER JOIN $Документ.Хустановка AS ДокХол ON $Хснятие.ДокументУ = ДокХол.IDDOC
INNER JOIN $Справочник.Контрагенты AS Контр ON $ДокХол.Контрагент=Контр.ID
WHERE (Журнал.ISMARK = 0)
AND (Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата))
UNION ALL
SELECT ДокХол.IDDOC
, $ДокХол.Холодильник
, $ПустойИД
, CAST(Left(Журнал.DATE_TIME_IDDOC, 8) AS DateTime)
FROM $Документ.Хремонт AS ДокХол
LEFT OUTER JOIN _1SJOURN AS Журнал ON ДокХол.IDDOC = Журнал.IDDOC
WHERE ((Журнал.CLOSED & 1) = 1)
AND (Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата)
AND ($ДокХол.ВидОперации = :ВыбОперация)
[/code]

Нарисовал на одном дыхании, так что проверь. Должно по идее работать нормально. Удачи
  

Если у вас есть деньги тогда мы идем к вам!!!
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать