Nano Hash - криптовалюты, майнинг, программирование

Проблема с суммой SQL-запроса

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

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

SQL:

SELECT customers.id                                      AS 'Customer ID', 
       customers.firstname                               AS 
       'Customer First Name', 
       customers.lastname                                AS 'Customer Last Name' 
       , 
       users.firstname                                   AS 
       'Employee First Name', 
       users.lastname                                    AS 'Employee Last Name' 
       , 
       positions.currency                                AS 'Currency', 
       Sum(customer_deposits.amount)                     AS 'Total Deposits', 
       Sum(positions.status)                             AS 'Total Bets', 
       Sum(customer_total_statistics.totalbonusdeposits) AS 'Total Bonuses', 
       positions.date                                    AS 'Date' 
FROM   customers 
       LEFT JOIN customer_deposits 
              ON customers.id = customer_deposits.customerid 
       LEFT JOIN users 
              ON customers.employeeinchargeid = users.id 
       LEFT JOIN positions 
              ON customers.id = positions.customerid 
       LEFT JOIN customer_total_statistics 
              ON customers.id = customer_total_statistics.customerid 
WHERE  customer_deposits.status = 'approved' 
       AND positions.status = 'won' 
       AND positions.date BETWEEN '2013-10-01' AND '2013-11-01' 
       AND customers.isdemo = '0' 
GROUP  BY customers.id 
ORDER  BY customers.id 
29.11.2013

  • Пожалуйста, научитесь правильно форматировать вопросы. Вы уже разместили более 50 постов. Используйте кнопку {} для форматирования кода. 29.11.2013

Ответы:


1

Ну, вы вообще не фильтруете свои customer_deposits, поэтому сумма поверх customer_deposits.amount, конечно, даст вам сумму всех депозитов. Вам придется добавить еще один, где фильтровать customer_deposits по дате, а не только по позициям.

29.11.2013
  • Что вы имеете в виду, я не фильтрую мои клиентские_депозиты ..? не могли бы вы расширить свой ответ. спасибо 29.11.2013
  • Вы фильтруете по position.date. Однако вы присоединяетесь к таблице customer_deposits, и единственный способ, которым они связаны, заключается в том, что вы не получаете клиентов, у которых не было позиций в течение этой даты. Однако вы всегда получаете все записи в customer_deposits для этих клиентов. Если возможно, я бы добавил новый фильтр where, and customer_deposits.date between '2013-10-01' and '2013-11-01'. Другими словами, если вы не присоединяетесь к позициям напрямую, вы всегда получаете все данные о клиентах. В этом случае вы должны фильтровать каждую таблицу отдельно. 29.11.2013

  • 2

    Похоже, у вас есть несколько отношений 1-n, поэтому ваши соединения создают декартовы произведения. Итак, если у вас был клиент с 2 депозитами и 2 позициями:

    Positions                       customer_deposits
    
    CustomerID | Amount             CustomerID | Amount         
    1          |  10                    1      |  30
    1          |  20                    1      |  40
    

    Когда вы сделаете это, присоединитесь:

    SELECT  c.ID, cd.Amount AS DepositAmount, p.Amount AS PositionAmount
    FROM    Customers c
            INNER JOIN customer_deposits cd
                ON c.ID = cd.CustomerID
            INNER JOIN Positions p
                ON c.ID = p.CustomerID
    

    В итоге вы получите 4 строки со всеми комбинациями суммы депозита и суммы позиции:

    ID  DepositAmount PositionAmount
    1       10              30
    1       10              40
    1       20              30
    1       20              40
    

    Поэтому, если вы суммируете это, вы получите неверные суммы, потому что строки дублируются. Вам нужно переместить ваши SUM в подзапросы:

    SELECT customers.id             AS 'Customer ID', 
           customers.firstname      AS 'Customer First Name', 
           customers.lastname       AS 'Customer Last Name',
           users.firstname          AS 'Employee First Name', 
           users.lastname           AS 'Employee Last Name',
           positions.currency       AS 'Currency', 
           cd.amount                AS 'Total Deposits', 
           P.status                 AS 'Total Bets', 
           cs.totalbonusdeposits    AS 'Total Bonuses', 
           positions.date           AS 'Date' 
    FROM   customers 
           INNER JOIN 
           (    SELECT  CustomerID, SUM(Amount) AS Amount
                FROM    customer_deposits 
                WHERE   customer_deposits.status = 'approved' 
                GROUP BY CustomerID
            ) cd
                  ON customers.id = cd.customerid 
           LEFT JOIN users 
                  ON customers.employeeinchargeid = users.id 
           INNER JOIN 
           (    SELECT  CustomerID, Date, SUM(Status) AS Status
                FROM    positions 
                WHERE   positions.status = 'won' 
                AND     positions.date BETWEEN '2013-10-01' AND '2013-11-01' 
                GROUP BY CustomerID, Date
            ) P
                ON customers.id = positions.customerid 
           LEFT JOIN 
           (    SELECT  CustomerID, SUM(totalbonusdeposits) AS totalbonusdeposits
                FROM    customer_total_statistics 
                GROUP BY CustomerID
            ) cs
                ON customers.id = customer_total_statistics.customerid 
    WHERE   customers.isdemo = '0';
    

    Обратите внимание: вы использовали поля в предложении where для таблиц, соединенных слева, что фактически превращает их во внутреннее соединение, например

    positions.status = 'won'
    

    Если в позициях нет совпадений, статус будет NULL, а NULL = 'won' оценивается как NULL (не верно), поэтому будут исключены все строки, в которых нет совпадений в position. Таким образом, я изменил ваше LEFT JOIN на INNER.

    29.11.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..