Имя: Пароль:
1C
1C 7.7
v7: 1SQlite: Как удалять записи из таблицы?
0 Zhuravlik
 
14.11.12
16:42
В базе мемори две таблицы: "Остатки" и "Отбор". Необходимо из остатков удалить все записи, которые есть в отборе.
Причем в отборе меньше колонок, чем в остатках, но те, которые есть - идентичны.
Создаю индекс для "Остатки", и пробую выполнить такой запрос:

DELETE FROM Остатки
WHERE Остатки.Вагон = Отбор.Вагон AND Остатки.Поставщик = Отбор.Поставщик AND Остатки.Договор = Отбор.Договор AND Остатки.Автомобиль = Отбор.Автомобиль


Мне говорят "no such column: Отбор.Вагон". Как это правильно делается? Я понимаю, что его надо как-то при-лефт-джойнить, указать что именно я хочу удалить, но не пойму как это описать в запросе.
1 Zhuravlik
 
14.11.12
16:49
Вроде можно так WHERE ОСТАТКИ.Вагон IN (SELECT ВАГОН FROM Отбор)? Но это для каждого поля надо описать такое условие, и выборка наверное будет очень громоздкой, ведь для каждой операции удаления я перебираю всю таблицу Отбор, да еще и для каждого поля...
2 mvk
 
14.11.12
16:49
DELETE FROM Остатки
FROM Остатки join Отбор on Остатки.Вагон = Отбор.Вагон AND Остатки.Поставщик = Отбор.Поставщик AND Остатки.Договор = Отбор.Договор AND Остатки.Автомобиль = Отбор.Автомобиль
3 Zhuravlik
 
14.11.12
16:55
DELETE FROM Остатки
WHERE Остатки.Вагон IN (SELECT Вагон FROM Отбор) AND
Остатки.Поставщик IN (SELECT Поставщик FROM Отбор) AND
Остатки.Договор IN (SELECT Договор FROM Отбор) AND
Остатки.Автомобиль IN (SELECT Автомобиль FROM Отбор)
Очистка записей: 0.009 мс

(2) Спасибо, сейчас попробую)
4 Ёпрст
 
14.11.12
16:58
(3) это не верный код.
5 mvk
 
14.11.12
16:59
(3) Не вздумай применить! Убьет много лишнего!
6 Zhuravlik
 
14.11.12
17:00
(4) Да, выдает ошибку.
DELETE FROM Остатки
FROM Остатки join

и

DELETE FROM Остатки join

(5) Что именно применить?
7 Zhuravlik
 
14.11.12
17:01
(5) База тестовая, а таблички - в памяти, ничего страшного.
Но сработало, кстати как надо...
8 mvk
 
14.11.12
17:03
(6) Код в (3) убьет лишнее, т.к. будет проверять не на точное совпадение совокупности, а просто на вхождение.

Какой сервер? Пример брал из справки 2008:
-- Transact-SQL extension
USE AdventureWorks2012;
GO
DELETE FROM Sales.SalesPersonQuotaHistory
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;
GO
9 Zhuravlik
 
14.11.12
17:04
(8) База ДБФ, я пишу запрос для ВК 1SQlite.
10 Ёпрст
 
14.11.12
17:06
можно и так:
DELETE FROM Остатки Остатки
where exists(select * from Отбор Отбор where
Остатки.Вагон = Отбор.Вагон AND Остатки.Поставщик = Отбор.Поставщик AND Остатки.Договор = Отбор.Договор AND Остатки.Автомобиль = Отбор.Автомобиль )
11 mvk
 
14.11.12
17:06
(3) Представь, что у тебя есть запись в остатках
Вагон = 5, Поставщик = Пупкин...
Точно такой строки в Отборе нет, но по отдельности есть и вагон 5 и Пупкин. В твоем запросе убьет такую запись в остатках.
12 Zhuravlik
 
14.11.12
17:07
(11) Но для того, чтобы этого не произошло я и поставил оператор AND. А, понял... Существую-то существуют, а друг с другом не соотносятся..
(10) Попробую сейчас, спасибо)
13 Ёпрст
 
14.11.12
17:08
(8) в скульлайте нет возможности удаления на основе соединения
14 Ёпрст
 
14.11.12
17:12
а так, всё это не нужно..
и уж лучше смотреть в сторону

intersect/except
http://www.sqlite.org/syntaxdiagrams.html#compound-operator

а еще лучше - отказ от временных табличек в памяти
15 Zhuravlik
 
14.11.12
17:12
(13) Получилось)
Только у вас "Остатки Остатки" и "Отбор Отбор" - зачем повторяются? СкульЛайт ошибку мне выдал, я сделал так:

DELETE FROM Остатки
WHERE exists(SELECT * FROM Отбор WHERE
Остатки.Вагон = Отбор.Вагон AND
Остатки.Поставщик = Отбор.Поставщик AND
Остатки.Договор = Отбор.Договор AND
Остатки.Автомобиль = Отбор.Автомобиль)
Очистка записей: 0.04
16 Ёпрст
 
14.11.12
17:14
какую ошибку ?
ЗЫ: писать лучше всегда с псевдонимами таблиц.
17 Zhuravlik
 
14.11.12
17:17
(14) Я временные таблички использую как аналог ИТЗ. Вот на таком коде:
       ИТЗ_Отбор = СоздатьОбъект("ИндексированнаяТаблица");
       ИТЗ_Отбор.Загрузить(Запрос.ВыполнитьЗапрос("SELECT * FROM Отбор"));
       ИТЗ_Отбор.ДобавитьИндекс("ИНД", г_КолонкиИсточника);
       ИТЗ_Остатки.ДобавитьИндекс("ИНД", г_КолонкиИсточника);
       ИТЗ_Остатки.Разность(ИТЗ_Отбор, "ИНД", "ИНД", 0);

Разность занимает  0.129мс, а в предидущем - 0.04)

(16) near "Остатки": syntax erro
18 Zhuravlik
 
14.11.12
17:18
(16) А, это псевдонимы) Я не понял.
19 Zhuravlik
 
14.11.12
17:19
(16) с "as" тоже выдает ошибку.
20 Ёпрст
 
14.11.12
17:20
дык псевдоним другой задай.
21 Zhuravlik
 
14.11.12
17:23
DELETE FROM Остатки as _Остатки
WHERE exists(SELECT * FROM Отбор as _Отбор WHERE
_Остатки.Вагон = _Отбор.Вагон AND
_Остатки.Поставщик = _Отбор.Поставщик AND
_Остатки.Договор = _Отбор.Договор AND
_Остатки.Автомобиль = _Отбор.Автомобиль)
Запрос.ВыполнитьЗапрос(ТекстЗапроса);
{Обработка.ПОДБОР_УНИ_РЕГ.Форма.Модуль(306)}: near "as": syntax error
22 Zhuravlik
 
14.11.12
17:24
+ без "as" то же самое
(14) Вчитываюсь, спасибо)
23 ДенисЧ
 
14.11.12
17:24
(21) ткни меня носом хоть в один мануал по сиквелу, где написано, что в делете можно использовать альясы для таблицы, из которой удаляем...
24 Zhuravlik
 
14.11.12
17:27
(23) Интересно, а есть такой, где написано, что нельзя?
25 Ёпрст
 
14.11.12
17:33
(23) да всё можно.. в скуле, так к примеру:

delete from table
from dbo.table as table
26 Ёпрст
 
14.11.12
17:35
а в скульлайте, мот и нельзя :)
смотреть синтаксис треба..
27 Zhuravlik
 
14.11.12
17:39
А как пишется:
UNION ALL EXCEPT? Ошибку пишет. И UNION EXCEPT - тоже ошибка.
28 Zhuravlik
 
14.11.12
17:42
Просто на UNION ALL тоже ошибка

"SELECTs to the left and right of UNION ALL do not have the same number of result columns"

Это потому что я UNION после ЛЕФТ-Джойна использую?
29 Ёпрст
 
14.11.12
17:42
два запроса должны иметь одинаковое количество колонок и в том же порядке..
30 Ёпрст
 
14.11.12
17:42
(или несколько запросов)
31 Zhuravlik
 
14.11.12
17:44
(30) Я так и подумал. Значит UNION не подходит, буду удалять. Спасибо за помощь)
32 Zhuravlik
 
14.11.12
17:47
(30) А вот вы в (14) сказали "еще лучше - отказ от временных табличек в памяти", а если их хранить не в памяти а на ЖД? Я думал, то что в памяти - оно быстрее.
33 Ёпрст
 
14.11.12
17:48
(32)это всё получить одним запросом.. сразу.
Либо пересмотреть структуру хранения данных.
34 Ёпрст
 
14.11.12
17:49
это всё лучше чем извлекать что-то запром, пихать во временную и еще и удалять строки в ней по условию..
35 Zhuravlik
 
14.11.12
17:58
(33) У меня подбор идет из документа. Остатки - это срез регистра, а Отбор - это ТабЧасть непроведенного документа, из которого идет отбор. При старте обработки я хочу ее из выборки исключать.
36 Zhuravlik
 
14.11.12
17:59
*которого идет отбор - которого идет ПОДБОР