Скрипт подсчета количества активных клиентов у дилеров.

Тема в разделе "Базы данных", создана пользователем repacksman, 1 окт 2015.

Модераторы: latteo
  1. repacksman

    repacksman

    Регистр.:
    12 июн 2012
    Сообщения:
    154
    Симпатии:
    2
    Даже не знаю с чего начать. Главная проблема в том что дилеры и пользователи находятся в одной и той же таблице "users". Клиента от дилера отличает то что у клиента в поле "dealer" стоит логин дилера. А чтоб определить активный ли клиент нужно в таблице "user_packet_groups" посмотреть если ли у него запись(их может быть несколько а может ни одной), где time_till>time().

    Подскажите как можно такое сделать? С чего начать? РНР скрипт будет запускаться по крону, считать количество клиентов и добавлять их дилеру в поле "client" в таблице "users"

    Вот структура таблиц:
    users

    login - dealer - client
    deale1 - -
    test1 - deale1 -
    test2 - deale1 -
    test3 - deale2 -

    user_packet_groups

    login - time_till
    test1 - 1436561448
    test2 - 1434541448
    test3 - 1494561448
     
  2. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.549
    Симпатии:
    1.433
    Один из вариантов:

    PHP:
    SELECT d.logincount(upg.loginFROM `usersd
    join 
    `usersu ON d.login u.dealer
    join 
    `user_packet_groupsupg ON u.login upg.login
    WHERE upg
    .time_till 1436561447
    Собственно инсёртить через php вовсе необязательно (похоже вы именно об этом подумывали), можно просто переписать этот запрос на апдейт.

    Дизайн таблиц плоховат, я бы в первой добавил unical id, которые использовал вместо login в остальных таблицах.

    Зачем по крону заполнять количество активных клиентов? Чаще всего, это можно считать каждый раз когда потребуется и будет всегда актуально и без головняка с кроном (за кроном имеют привычку не следить и он часто уходит в поломки)
     
  3. Jays

    Jays Создатель

    Регистр.:
    4 окт 2015
    Сообщения:
    15
    Симпатии:
    1
    С вашего позволения я немного добавлю активен дилер или нет:

    PHP:
    select d.logincount(upg.login),

    case 
        
    when upg.time_till is not null then
          
    'Active Dealer'
          
    when upg.time_till is null then
           
    'Not Active'
          
    end Dealer
    join 
    `usersu ON d.login u.dealer
    join 
    `user_packet_groupsupg ON u.login upg.login
     
  4. Роман Дмитриев

    Роман Дмитриев Создатель

    Регистр.:
    16 авг 2015
    Сообщения:
    14
    Симпатии:
    0
    Не понятно, как связаны дилеры и клиенты. Уточните?
     
  5. Jays

    Jays Создатель

    Регистр.:
    4 окт 2015
    Сообщения:
    15
    Симпатии:
    1
    В таблице users распознать можно только по логину
     
  6. Роман Дмитриев

    Роман Дмитриев Создатель

    Регистр.:
    16 авг 2015
    Сообщения:
    14
    Симпатии:
    0
    Слегка модернизируем первый вариант, так как насколько я понял у одного клиента может быть несколько пакетов, но это один клиент, а не несколько. Не уверен, что при использовании выражения count(upg.login) сервер понимает, что имеется в виду count(distinct upg.login). По крайней мере, в MS SQL это работает некорректно и будет считаться каждый активный пакет, а не количество клиентов. Так правильней:
    PHP:
    SELECT d.logincount(*) FROM `usersd
    join 
    `usersu ON d.login u.dealer
    WHERE exists
    (select 1 from `user_packet_groupsupg where u.login upg.login and upg.time_till 1436561447)
    group by d.login
     
    Последнее редактирование: 13 ноя 2015
  7. Jays

    Jays Создатель

    Регистр.:
    4 окт 2015
    Сообщения:
    15
    Симпатии:
    1
    Хочу сказать насчёт exists лучше мало им пользоваться из за перформанса, я всегда использую оператор minus в этих целях он в 50% быстро работает чем exists.
     
  8. Роман Дмитриев

    Роман Дмитриев Создатель

    Регистр.:
    16 авг 2015
    Сообщения:
    14
    Симпатии:
    0
    Возмозжно, в каких-то движках БД оператор EXISTS действительно работает не так быстро. В MS SQL и MySQL работает быстрее, чем JOIN на все записи. Кроме этого, оператор MINUS есть также не во всех движках БД. Есть аналоги этого оператора, которые работают медленнее EXISTS.
     
  9. Jays

    Jays Создатель

    Регистр.:
    4 окт 2015
    Сообщения:
    15
    Симпатии:
    1
    Оператор minus есть во всех известных движках, MS SQL не интересуюсь так как был плохой опыт поднять на нем DWH (я сам BI DWH специалист), и по этому по работе могу сказать что exists это очень плохо.
     
  10. Роман Дмитриев

    Роман Дмитриев Создатель

    Регистр.:
    16 авг 2015
    Сообщения:
    14
    Симпатии:
    0
    "У меня не получилось что-то сделать, поэтому считаю, что это плохо." Аргумент :)
    На счет оператора MINUS - в MS SQL его нет. В MySQL его не нашёл. Вот ссылка на текущую документацию MySQL http://dev.mysql.com/doc/
    Может я плохо искал?