Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Знатоки SQL помогите...

2.1K
21 декабря 2007 года
FreeWay
142 / / 03.05.2007
Всем привет, такая вот задачка:
У меня есть таблица, там 5000 записей, поле счет это клиент, тоесть поля счет постоянно дублируются (так как клиент может придти сегодня, завтра, и делать разне операции), задача в том, чтобы отобрать записи удовлетворяющие некоторому критерию:

Query1->SQL->Add("Select * From PROV Where ODAT<'12/21/2004' and OPER!='6'");

это работает, записей теперь 1000, но теперь надо избавится от дублирующих записей, тоесть должна быть одна запись по каждому клиенту, клиентов 300, значит и записей триста. Что то типа так:

Query1->SQL->Add("Select (Select distinct schet From PROV Where ODAT<'12/21/2004' and OPER!='6') schet, oper, summa, odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'");

ругается - подзапрос выводит больше одной строки ((

пробовал так:
Query1->SQL->Add("Select distinct * From PROV Where ODAT<'12/21/2004' and OPER!='6'");

но он почему то группирует одинаковые счета, а не исключает их((


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

что то типа такого Query1->SQL->Add("Select distinct (schet), oper, summa, odat, numo From PROV ");

но этот синтаксис неправильный

пробовал и так
Select schet, oper, summa, odat, numo
From PROV
Where ODAT<'12/21/2004' and OPER!='6'
GROUP BY schet

отобрал, вначале идут счета попорядку, но потом задваиваются - тоесть есть дубли
11
21 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
тоесть должна быть одна запись по каждому клиенту, клиентов 300, значит и записей триста


насколько я понял из столь путанного объяснения:

INNER JOIN с таблицей клиентов

2.1K
21 декабря 2007 года
FreeWay
142 / / 03.05.2007
Цитата: oxotnik333
насколько я понял из столь путанного объяснения:

INNER JOIN с таблицей клиентов



та не, таблица только одна, в этой таблице куча проводок, кучи клиентов, задача выбрать проводки по критерию, так как за период времени один клиент мог до сотни раз делать операции мне надо отсечь дубли, тоесть задача - узнать попадает ли клиент в даный критерий, мне не надо сотню его операций, только одна, и так по все клиентам.

а теперь понятней?? ))

11
21 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: FreeWay
та не, таблица только одна, в этой таблице куча проводок, кучи клиентов, задача выбрать проводки по критерию, так как за период времени один клиент мог до сотни раз делать операции мне надо отсечь дубли, тоесть задача - узнать попадает ли клиент в даный критерий, мне не надо сотню его операций, только одна, и так по все клиентам.

а теперь понятней?? ))



тогда SELECT COUNT выдает количесво записей
фильтруешь по клиенту и делаешь подсчет

2.1K
21 декабря 2007 года
FreeWay
142 / / 03.05.2007
та мне не колличество записей, а сами записи
11
21 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: FreeWay
та мне не колличество записей, а сами записи


Цитата: FreeWay
тоесть задача - узнать попадает ли клиент в даный критерий



если записей >0 то попадает, если ==0 значит не попадает

1
22 декабря 2007 года
kot_
7.3K / / 20.01.2000
Цитата: FreeWay
та не, таблица только одна, в этой таблице куча проводок, кучи клиентов, задача выбрать проводки по критерию, так как за период времени один клиент мог до сотни раз делать операции мне надо отсечь дубли, тоесть задача - узнать попадает ли клиент в даный критерий, мне не надо сотню его операций, только одна, и так по все клиентам.

а теперь понятней?? ))


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

 
Код:
Select schet, MAX(oper), summa,odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'"
GROUP BY schet

например.
2.1K
24 декабря 2007 года
FreeWay
142 / / 03.05.2007
FoxPro, использую компонент BDE

Select schet, MAX(oper), summa,odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'"
GROUP BY schet

использовал этот код в самых разных вариантах, везде выдает:
error "when group by exist, every simple field in projectors must be in group by"
8.2K
24 декабря 2007 года
Ora-cool
211 / / 20.09.2007
Цитата: FreeWay
FoxPro, использую компонент BDE

Select schet, MAX(oper), summa,odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'"
GROUP BY schet

использовал этот код в самых разных вариантах, везде выдает:
error "when group by exist, every simple field in projectors must be in group by"



Ну неудивительно. При селекте с группировкой в выборке должны быть либо поля, входящие в группировку либо агрегирующие функции

2.1K
24 декабря 2007 года
FreeWay
142 / / 03.05.2007
чуть чуть подкорректировал
Select schet, MAX(oper), summa, odat, numo From PROV Group by schet,summa,odat,numo

все равно немного не то, будемс додумывать ))
11
24 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Select schet, MAX(oper), summa,odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'"
GROUP BY schet, summa,odat, numo

ЗЫ: В любом SQL билдере при агрегации какого нидь поля автоматом в групировку попадают все остальные поля
ЗЫЗЫ: В любой СУБД и в БДЕ в частности есть этот самый билдер
8.2K
24 декабря 2007 года
Ora-cool
211 / / 20.09.2007
Не знаю, сработает ли это для FoxPro, но если у вас есть в таблице уникальный идентификатор (первичный ключ), то можно так:

 
Код:
select p1.schet, p1.summa, p1.odat, p1.numo
  from PROV p1,
  (select max(id) id, schet from PROV
    where ODAT<'12/21/2004' and OPER!='6'
    group by schet) p2
  where p1.id = p2.id

где id -идентификатор записи
ну или через явный inner join

 
Код:
select p1.schet, p1.summa, p1.odat, p1.numo
  from PROV p1
  inner join
  (select max(id) id, schet from PROV
    where ODAT<'12/21/2004' and OPER!='6'
    group by schet) p2
  on p1.id = p2.id

Идея в том, что сначала находим идентификаторы записей (во вложенном селекте) на каждый счет (берем, например макс. id для каждого счета), если такие есть, а затем выбираем всю информацию для записей с найденными идентификаторами.
8.2K
24 декабря 2007 года
Ora-cool
211 / / 20.09.2007
Цитата: oxotnik333
Select schet, MAX(oper), summa,odat, numo From PROV Where ODAT<'12/21/2004' and OPER!='6'"
GROUP BY schet, summa,odat, numo

ЗЫ: В любом SQL билдере при агрегации какого нидь поля автоматом в групировку попадают все остальные поля
ЗЫЗЫ: В любой СУБД и в БДЕ в частности есть этот самый билдер


Не думаю, что это то что нужно автору. Я так понял ему нужна 1 запись на каждый счет, а здесь будет далеко не 1 запись

11
24 декабря 2007 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Ora-cool
Не думаю, что это то что нужно автору. Я так понял ему нужна 1 запись на каждый счет, а здесь будет далеко не 1 запись



Я если чесно запутался что нужно, толь счет, толи признак того делал ли некий юзер за определенный период какую либо операцию.
Я написал для последнего варианта.

9.9K
06 января 2008 года
maxFM
77 / / 18.04.2007
Есои тебе необходимо только вывести список клиентов по условиям запроса тогда тебе необходимо и выводить только это поле с группировкой.
и запрос будет гдето такой
"Select id_client where date.....(условие) group by id_client"
в этом случае он не будет дублировать.
30K
20 января 2008 года
noi
5 / / 19.06.2007
Цитата: FreeWay
чуть чуть подкорректировал
Select schet, MAX(oper), summa, odat, numo From PROV Group by schet,summa,odat,numo

все равно немного не то, будемс додумывать ))



В вашем случае, в соответствии с данным запросом, будет отобрано всё множество, элементы которого различны.. Т.е. schet, MAX(oper), summa, odat, numo есть: счета – группируются, выполняется DISTINCT: summa – группируются частично, т.к. энтропия значений велика (ну разные суммы, они все «уникальны»…); odat – тоже само по себе.. numo – аналогично, то же имеет собственную уникальность.. В совокупности, мы имеем множество не связанных и различных наборов записей, которые нам и вернуться вероятно полностью, или за редким исключением группировкой тех записей – которые отличаются по какому то одному признаку.
В общем, суть сказанного такова – если вы хотите сгруппировать записи, то для групп нужны поля, которые «одинаковы».. а по остальным выполнить агрегатные функции.
Например:
schet, oper, summa, odat, numo
1 1 1 12/01/2007 1
2 1 1 12/01/2007 1
1 1 1 12/01/2007 1
3 1 1 12/01/2007 1
3 1 1 13/01/2007 1


SELECT schet, SUM( oper) as SumOper, summa, odat, numo FROM TABLE
GROUP BY SHET, SUMMA, ODAT, NUMO

Вернет:
schet, oper, SumOper, odat, numo
1 2 1 12/01/2007 1
2 1 1 12/01/2007 1
3 1 1 12/01/2007 1
3 1 1 13/01/2007 1

Как видно, сгруппировались только счет № 1 по дате 12/01/2007, в то же время, на 13/01/2007 мы получили «дубль» счета…

По этому, для «группировки», надо так «продумать» условие и поля для группировки – что бы в группу могли попасть только записи с одинаковым значением (вся строка, за исключением суммируемых и т.д. «вычисляемых» полей) и если надо, результат агрегатных функций.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог