:: Visual Foxpro, Foxpro for DOS
Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Пить меньше надо, а больше не надо, это банально ) Да, это когда в руке неуверенно держишь, мышку. В идеале совсем бы не держать, конечно...


Еще маленький вопрос. Обьединяю LEFT JOIN поля двух табличек fа5 и f9. Ожидаю, что в выходной табличке будет количество строк такое-же как в f5. Но количество записей становится немного больше, и сумма по ее некоторму полю "сумма" больше, похоже в табличке справа есть двойные записи. Означает ли наличие двойных записей справа их диблирование также и слева, т.е. в выходной табличке после обьединения? (нет времени проверять, может это очевидный вопрос и ответ):
SELECT f5.*,;
f9.ДоговорЮРд, f9.Вкладчик;
FROM (m.b) f5;
LEFT JOIN (m.b9) f9 ON f5.ИПС=f9.ИПС AND f5.сг_код=f9.сг_код;
INTO CURSOR (m.a9) READWRITE



Исправлено 1 раз(а). Последнее : ssa, 21.01.20 22:30
Ratings: 0 negative/0 positive
Re: Всякая всячина...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
Да.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Блин, свинство
Как избежать? левую таблицу менять нельзя... Правую сделать без дублей?
Ratings: 0 negative/0 positive
Re: Всякая всячина...
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
of63
Блин, свинство Как избежать? левую таблицу менять нельзя... Правую сделать без дублей?
Наверно...

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Вот так стало хорошо (левая таблица не изменилась, на правую немного плевать, она не ходовая)
SELECT f5.*,;
f9.ДоговорЮРд, f9.Вкладчик DISTINCT;
FROM (m.b) f5;
LEFT JOIN (m.b9) f9 ON f5.ИПС=f9.ИПС AND f5.сг_код=f9.сг_код;
INTO CURSOR (m.a9) READWRITE

Ну, не совсем не изменилась, проверочная функция
SELECT SUM(Сумма), COUNT(*) AS cnt FROM (m.a9)
возвращает cnt на 1 больше. Искать не буду, сумма совпала, и пвнх )

Для себя.
В одном запросе оказалось невозможно использовать два и более COUNT(DISTINCT поле), при исполнении ругается на "неверное выражение", или скобку, не помню. Это плохо. Приходится создавать пустое поле, и потом его дозаполнять этими DISTINCT-ами. Хз, в хелпе не нашел описание этого, может это нештатное.



Исправлено 3 раз(а). Последнее : of63, 22.01.20 01:27
Ratings: 0 negative/0 positive
Re: Всякая всячина...
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Если с любой стороны будет "дубликат" по ключевым полям (по тем которым соединяешь таблицы, то и записей по такому ключу в результате будет две. Если дубликаты будут с 2 сторон, то получим перемножение. т.е. 4 записи (если дублей всего по 2 записи). LEFT/RIGHT соединение можно рассматривать как обычное INNER JOIN дополненное "потерявшимися" записями из одной из таблиц. INNER JOIN же всегда "перемножает" наборы.

DISTINCT только один разрешён на запрос, это да. Но в данном случае DISTINCT вряд ли поможет - поможет GROUP BY по ключевым полям - для той таблицы где есть непредусмотренные дубли. В этом примере, судя по всему, это GROUP BY для таблицы f9 по полям ИПС и сг_код. Что именно брать для полей ДоговорЮРд и Вкладчик - загадка природы. Проще всего какой-нить MIN/MAX - если пользователям пофиг что записи задублированы, то им наверное не менее пофиг какие поля из каких записей попадут в результат. Если же есть какое-то третье поля, которое однозначно позволит отобрать одну "правильную" запись, то можно соорудить 2-этажный запрос. Сначала выбрать правильные тройки из ключевые поля + поле выбора правильного дубликата, а потом уже применив такие тройки к таблице ещё раз - вынуть все поля соответствующей записи. В принципе в качестве суррогата такого поля выбора "правильного дубля" можно для фокса применить RECNO.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Чето я думал, что LEFT JOIN оставляет количество записей слева неизменным... Ну буду знать, что на этой дороге знак висит.

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

Вобщем, дополнение таблицы (без ее нарушения) полями из другой таблицы при помощи JOIN оказалось невозможным? Ну, или дубликаты предварительно убирать в правой таблице, но это уже не одна строка программы. Так код и растет, за 10-20 лет обрастает таким мхом, что...

> DISTINCT только один разрешён на запрос
Я имел ввиду не DISTINCT на строку, а именно COUNT(DISTINCT поле) - счетчик уникальных вхождений значения поля. Оказалось, что два и более таких счетчика в запросе указать нельзя. Опять исчезает наитивность кода, приходится делать довыборки на каждый такой счетчик в отчете...
Ratings: 0 negative/0 positive
Re: Всякая всячина...
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Чето я думал, что LEFT JOIN оставляет количество записей слева неизменным... Ну буду знать, что на этой дороге знак висит.
JOIN это логика "перемножения множеств" а не логика a-la set relation. left/right/full лишь добавляют к "базе" создаваемой inner join "потеряшек".
of63
Реально, эти дубликаты настолько дубликаты, что пофик какой из них попадет в отчеты.
Потому я и написал - в простых случаях хватает group by ключи и min(неключевое_поле), или max() - без разницы.
of63
DISTINCT на строку там неуместен, но как-то сработало в данном случае..
Повезло. Была бы там группировка, и никакой distinct не спас бы от удвоения/учетверенния/увосьмирения суммируемых данных. А group by в подзапросе для "кривого справочника" - помогает.

of63
> DISTINCT только один разрешён на запрос
Я имел ввиду не DISTINCT на строку, а именно COUNT(DISTINCT поле)
Без разницы - он просто один на запрос допустим - внутри агрегирующей функции, или снаружи. Ограничение движка.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> JOIN это логика "перемножения множеств" а не логика a-la set relation.

Похоже, что если явно JOIN не указывать, а указать извлечение из двух таблиц, связав их в выражении WHERE, то все равно записи будут перемножены? (это можно проверить, но вдруг ответ очевиден...)
SELECT f5.*,;
f9.ДоговорЮРд, f9.Вкладчик DISTINCT;
FROM (m.b) f5;
WHERE f5.ИПС=f9.ИПС AND f5.сг_код=f9.сг_код

Доб. Заодно в тему, два вопроса к фоксистам и к ИК :
1. Кто как добавляет поля справа к левой табличке? При условии что и в левой и в правой есть дубликаты. Левую табличку изменять нельзя.
2. Как в табличке пронумеровать записи-дубликаты? С целью, чтобы потом, например, удалить все записи с номером 1, и останутся только кратные записи, или наоборот - удалить все записи с номером 2 и более, тогда останется по единственной записи.

Перебором в SCAN, использованием уникального фоксового индекса, я умею. А вот как это сделать фоксовым SQL-запросом? Заранее благодарен за варианты.



Исправлено 1 раз(а). Последнее : of63, 27.01.20 14:57
Ratings: 0 negative/0 positive
Re: Всякая всячина...
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Похоже, что если явно JOIN не указывать, а указать извлечение из двух таблиц, связав их в выражении WHERE, то все равно записи будут перемножены? (это можно проверить, но вдруг ответ очевиден...)
Этот синтаксис аналогичен синтаксису с INNER JOIN. В старых версиях стардарта SQL и в некоторых старых СУБД это был единственный вариант "соединения" таблиц. Естественно что работает он точно так же.
of63
1. Кто как добавляет поля справа к левой табличке? При условии что и в левой и в правой есть дубликаты. Левую табличку изменять нельзя.
Написал же - запросом с GROUP BY из "плохой таблицы" делается кривоватый, но таки без дублей курсор. Кому сложно читать большой код - отдельной командой SELECT ... INTO CURSOR, кому не сложно - подзапросом.
SELECT ... FROM Main LEFT JOIN (SELECT SomeId, MAX(Name) Name FROM Some GROUP BY SomeId) FixedSome ON Main.SomeId = FixedSome.SomeId ...
of63
2. Как в табличке пронумеровать записи-дубликаты? С целью, чтобы потом, например, удалить все записи с номером 1, и останутся только кратные записи, или наоборот - удалить все записи с номером 2 и более, тогда останется по единственной записи.
используя recno в многоуровневых подзапросах - надо искать примеры Леонида, он показывал. Но это криво и ненадёжно, лучше взять какое-то значимое поле из таблицы, добавление которого устранит дубликаты, и уже по нему разделять в каждой группе дубликатов кого оставлять, а кого удалять.
А на будущее - позаботиться о наличии уникальных индексов в таблице.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Всякая всячина...
of63
Автор

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Про вопрос 2 не имею ничего против решения Леонида. RECNO() как заменитель ID понятен и очевиден. Пут леонида громоздок, но и тьы не сказал решения, сославшись на отсутствие ИД (его просто получить в фоксе, это RECNO(), как вы и заметили и согласны)

Сомневаюсь, что еесли вы не нуменуете одной SQL-строкой, то мне думать уже не надо в поисках семантики и синтаксиа. И на том спс.

() ИК. ты блин, все "знаешь", это как-то потосриттельно...

() пипец нам всем походу, ИК все более краток и краток... Сами седла отрывайте от скакунов, Давайте программируйте, и радуйте результатами, вашу мать! Особенно Симпле желаю удачи, чтобы ДОС не сломали, ...ведь лет 50 стоИт... круто, железно, по-мужски! )



Исправлено 1 раз(а). Последнее : of63, 27.01.20 23:46
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 35 Nike  (Гостей: 34)

© 2000-2024 Fox Club 
Яндекс.Метрика