Topic: Динамическая дата на графике

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

Re: Динамическая дата на графике

Приветствую,


Вам необходимо сделать SQL запрос, который сгрупирует количество записей в БД по дате, пример:

SELECT COUNT(*), datefield FROM tablename ORDER BY datefield GROUP BY datefield

далее просто подставить этот запрос в проект с примером создания графика на форме.

Dmitry.

3 (edited by memult 2016-06-02 10:52:53)

Re: Динамическая дата на графике

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

Re: Динамическая дата на графике

memult
С данным запросом кривая не будет идти все время вверх. Запрос вернет данные следующего вида

01.05.2016 - 5 записей
02.05.2016 - 4 записей
03.05.2016 - 0 записей
04.05.2016 - 3 записей
05.05.2016 - 8 записей

Dmitry.

5 (edited by memult 2016-06-02 12:27:43)

Re: Динамическая дата на графике

Да,я понимаю. Но нужно другое:
01.05.2016 - 5 записей (общее-5)
02.05.2016 - 4 записей (общее-9)
03.05.2016 - 0 записей (общее-9)
04.05.2016 - 3 записей (общее-12)
05.05.2016 - 8 записей (общее-20)

Таким образом на 05.05.2016 получаем 20 записей, а на 01.05.2016 имели 5 записей. Таким образом график идет всегда вверх. Нужно именно это. А запрос выше возвращает, то,что Вы описали. Прикрепил пример,того, что нужно.

Post's attachments

Attachment icon пример.png 6.33 kb, 320 downloads since 2016-06-02 

Re: Динамическая дата на графике

memult
Называется нарастающий итог, тогда запрос будет таким

SELECT date, 
(SELECT COUNT(*) FROM line_data ln WHERE ln.date <= line_data.date) as incCount 
FROM line_data 
GROUP BY date 
ORDER BY date DESC
Dmitry.

7 (edited by memult 2016-06-02 13:59:25)

Re: Динамическая дата на графике

DriveSoft wrote:

memult
Называется нарастающий итог, тогда запрос будет таким

SELECT date, 
(SELECT COUNT(*) FROM line_data [b]ln[/b] WHERE [b]ln.date[/b] <= line_data.date) as incCount 
FROM line_data 
GROUP BY date 
ORDER BY date DESC

А не подскажете, что значит выделенные символы в запросе?(ln и ln.date) Таблица для запроса это line_data.
И какое в этом случае подставлять значение в строку ProfitValue := Results.FieldByName('count(*)').asString; Вместо count(*) ?
Если убрать в запросе  ln WHERE ln.date <= line_data.date,а значение ProfitValue := Results.FieldByName('incCount').asString;
то получается так:

Post's attachments

Attachment icon Скриншот (02.06.2016 16-56-26).jpg 52.49 kb, 370 downloads since 2016-06-02 

Re: Динамическая дата на графике

memult wrote:

А не подскажете, что значит выделенные символы в запросе?(ln и ln.date) Таблица для запроса это line_data.
И какое в этом случае подставлять значение в строку ProfitValue := Results.FieldByName('count(*)').asString; Вместо count(*) ?

ln это псевдоним таблицы line_data, это необходимо, чтобы можно было построить данное условие

ln.date <= line_data.date

чтобы различать таблицу основного запроса и таблицу в подзапросе, иначе мы просто будем сравнивать одни и теже данные, что не имеет смысла.


ProfitValue := Results.FieldByName('incCount').asString;
Dmitry.

Re: Динамическая дата на графике

Я Вас понял, спасибо. Только Вы пропустили AS в данном запросе.

10 (edited by memult 2016-06-03 09:21:02)

Re: Динамическая дата на графике

Запрос работает на SQLite,но не работает с MySQL.Скрипт построения графика:

{== LINE CHART ===========================================================================================}
procedure Stats_bLineUpdate_OnClick (Sender: string; var Cancel: boolean);
var
    Results: TDataSet;
    DateValue: Double;

    ProfitValue: string;

begin
    ChartLine.Series[0].Clear;


    SQLQuery('SELECT Начало,,Percent.Проценты,(SELECT COUNT(*) FROM employees as ln WHERE ln.Начало <= employees.Начало) as incCount FROM employees LEFT OUTER JOIN Percent ON Percent.id=employees.id_percent WHERE Percent.Проценты <> "100%"  GROUP BY Начало ', Results);

    while not Results.Eof do
    begin
        DateValue := SQLDateTimeToDateTime(Results.FieldByName('Начало').asString );
        ProfitValue := Results.FieldByName('incCount').asString;

       if ValidFloat(ProfitValue) then ChartLine.Series[0].AddXY(DateValue,StrToFloat(ProfitValue));

        Results.Next;
    end;
end;
{== LINE CHART ===========================================================================================}

Выдает ошибку: 21.04.2014 is not a valid date and time . Проблема,как я понимаю в формате поля "Начало". Пробовал в запросе после SELECT добавить функции DATE_FORMAT и str_to_date - не работает.

11 (edited by memult 2016-06-06 08:16:42)

Re: Динамическая дата на графике

С датой разобраться получилось, почему-то MySQL в моем примере понимает только формат даты 2016-04-01. к примеру.

Но теперь проблема с условием WHERE , даже если брать Ваш запрос:

SELECT date, 
(SELECT COUNT(*) FROM line_data ln WHERE ln.date <= line_data.date) as incCount 
FROM line_data 
GROUP BY date 
ORDER BY date DESC

Если мне нужно еще поставить условие WHERE,куда его ставить тут? во вложенный запрос не получится,как я понимаю, после вложенного тоже непонятно,т.к он не будет просто работать корректно.- показывается все равно общее количество записей,независимо от дополнительного условия WHERE..
Например если дополнить его так:
SELECT date, status
(SELECT COUNT(*) FROM line_data ln WHERE ln.date <= line_data.date) as incCount
FROM line_data WHERE Status="1"
GROUP BY date

UPD :как я понимаю, ставить дополнительные условия where нужно все таки во вложенный блок Select, поправьте если это не так.
И наверно основой вопрос, для чего и делался этот запрос :допустим запрос выдаёт количество записей, статус которых равен 1(Status=1).И строится график количество от даты.
Цель в следующем, проследить как менялось то или иное количество записей в таблице с течением времени(не добавилось за какую то дату, а именно чтобы записи суммировались все) . Т. Е например на 01.06.2016  их было 10, 02.06.2016 - 15 записей, а вот 03.06.2016 их стало допустим 13(2 записи удалили, либо статус сменился со Status =1  на другой любой) График продолжит расти(просто уберет одну точку из области построения графика) , хотя как раз в дате 03.06.2016 он должен идти на спад. Неужели такую динамику проследить никак не получится?

Re: Динамическая дата на графике

memult

Если мне нужно еще поставить условие WHERE,куда его ставить тут?

WHERE необходимо поставить как в основной запрос, так и в подзапрос.

SELECT date, status
(SELECT COUNT(*) FROM line_data ln WHERE ln.date <= line_data.date AND Status=1) as incCount 
FROM line_data WHERE Status=1
GROUP BY date

И наверно основой вопрос, для чего и делался этот запрос

в таком случае вам необходимо реализовать логгирование создание, редактирование и удаление записей, чтобы например в базе оставалась информация, когда запись была удалена либо был сменен ее статус. В данной теме можете найти пример логгирование записей
http://myvisualdatabase.com/forum/viewtopic.php?id=702

Dmitry.

Re: Динамическая дата на графике

Я пробовал делать это с помощью логгирования, но в этом случае непонятно,как учитывать записи у которых например сменился статус? Если брать конкретный пример:
01.05.2016 - Добавили 5 записей (общее-5,Статус=1)
02.05.2016 - Добавили 4 записей (общее-9,Статус=1)
03.05.2016 - Добавили 0 записей (общее-9,Статус=1)
04.05.2016 - Добавили 3 записей (общее-12,Статус=1)
05.05.2016 - Добавили 8 записей (общее-20,Статус=1)
06.05.2016 - Изменили статус двух из 5 добавленных 01.05.2016 записей на Статус=2 ( Общее количество записей на 06.05.2016 должно быть теперь не 20,а 18 и график в дате 06.05.2016 идти вниз - как на рисунке.)
Но,смысл логов просто записывать действия,к примеру изменился этот статус и в таблицу логов добавилась еще одна запись, что типо запись обновлена - вычитания же никакого не произойдет. Это учитывая что в запросе на построения графика стоит условие  только записи со Статус=1.Еще непонятная ситуация- новые записи в логи добавляются, общее количество считается Count'ом и таким образом будут считаться все строки,даже относящиеся к одной записи. Группировать в таком случае по id_EMP ? Т.е по идентификатору задачи? А как тогда быть с группировкой по дате?

Post's attachments

Attachment icon пример.png 7.15 kb, 282 downloads since 2016-06-07 

Re: Динамическая дата на графике

memult
К сожалению решения для данной задачи не подскажу, т.к. для ее решения необходимо слишком много времени, что выходит за рамки поддержки.

Dmitry.

Re: Динамическая дата на графике

Задача сложна именно в реализации? или в самой идее? Если в реализации,может тогда подскажите тогда общую схему реализации на словах? С чего начать и что нужно?

Re: Динамическая дата на графике

memult wrote:

Задача сложна именно в реализации? или в самой идее? Если в реализации,может тогда подскажите тогда общую схему реализации на словах? С чего начать и что нужно?

К сожалению с ходу не могу назвать схему реализации. Возможно задачу получиться решить каким либо сложным SQL запросом, за помощью можете обратиться на специализированный форум, например
http://www.sql.ru/forum/db-design
http://www.cyberforum.ru/database/

Dmitry.

17 (edited by memult 2016-06-10 08:59:03)

Re: Динамическая дата на графике

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

SQLQuery('SELECT DATE_Format(dateR,"%Y-%m-%d") AS dateR, (SELECT COUNT(*) FROM line_data as ln LEFT OUTER JOIN my ON my.id=ln.id_my WHERE ln.dateR <= line_data.dateR) as incCount from line_data GROUP BY dateR', Results);

Второй график выводит какое количество записей со статусом=1 добавлено в конкретную дату (синий):

SQLQuery('SELECT DATE_Format(dateR,"%Y-%m-%d") AS dateR,Count(*) from line_data LEFT OUTER JOIN my ON my.id=line_data.id_my WHERE my.my="Статус_1" GROUP BY dateR', Results);

Я так понимаю, задача может быть решена если мы вычтем из графика с общим количеством записей (Оранжевый) график который выводит какое количество записей со статусом=1 добавлено в конкретную дату (синий).Т.е нужно вычесть один запрос из другого и по сути нужно вычесть из общего количества,количество которое получается вторым запросом.Возможно Вы подскажите как это сделать?

Рисунок в приложении. Красный дорисованный график  это по сути и есть результат вычитания двух графиков.
Т.е здесь должна работать обычная алгебра: Есть Х- это задачи со статусом_1.Есть Y-задачи со статусом_2 (их и нужно получить после вычитания). Есть общее количество записей статус_1+статус_2 =Z. Получаем X+Y=Z . НУжно получить Y=Z-X. Это я и пытаюсь сделать.

Post's attachments

Attachment icon График.png 15.01 kb, 388 downloads since 2016-06-10 

18 (edited by memult 2016-06-14 11:36:32)

Re: Динамическая дата на графике

Не получится помочь с этим вопросом? На предложенных Вами форумах молчание.

Re: Динамическая дата на графике

memult wrote:

Не получится помочь с этим вопросом? На предложенных Вами форумах молчание.

Увы, с этим вопросом не смогу помочь.

Dmitry.