2016-09-22 1 views
0

Мне нужно использовать сложный запрос с объединениями, подзапросами и т. Д. В php-скрипте для генерации Json для процесса обработки на основе данных. Datatables не принимает подзапросы, поэтому мне нужен «плоский» запрос. Я думал о генерации представления, но подзапросы не принимаются ни на представления MySQL! Вот запрос MySQL. Чтобы вы посоветовали ?Комплексный запрос MySQL: решение для работы с представлениями (datatables ...)

SELECT a.Customers 
    ,a.Agent 
    ,a.status_name AS Current_Status 
    ,round(c.LTGGR - e.LT_TotBonus, 0) AS LT_NGR 
    ,CONCAT (
     round(e.LT_TotBonus/c.LTRM * 100, 0) 
     ,'%' 
     ) AS LT_Bonus_RM_per 
    ,CONCAT (
     'x' 
     ,round(c.LTBETS/(c.LTRM + e.LT_TotBonus), 0) 
     ) AS LT_Wagering 
    ,coalesce(d.Last_30D_RM, 0) AS Last_30D_RM 
    ,coalesce(d.Last_30D_NGR, 0) AS Last_30D_NGR 
    ,coalesce(g.CashBack_Last30D, 0) AS Cash_Back_30D 
    ,CONCAT (
     (f.cash_back_BO_per * 100) 
     ,'%' 
     ) AS status_cash_Back_BO_per 
    ,CONCAT (
     f.cash_back_per * 100 
     ,'%' 
     ) AS cash_back_percent 
    ,CASE 
     WHEN f.cash_back_per = 0 
      THEN 0 
     WHEN c.LTGGR - e.LT_TotBonus < 0 
      THEN 0 
     WHEN d.Last_30D_RM < 0 
      THEN 0 
     WHEN e.LT_TotBonus/c.LTRM * 100 >= f.cash_back_BO_per * 100 
      THEN 0 
     WHEN round(d.Last_30D_NGR * f.cash_back_per, 0) - coalesce(g.CashBack_Last30D, 0) < 0 
      THEN 0 
     WHEN isnull(d.Last_30D_NGR) 
      THEN 0 
     WHEN d.Last_30D_NGR < 0 
      THEN 0 
     ELSE round(d.Last_30D_NGR * f.cash_back_per, 0) 
     END AS cash_back_calc 
    ,CASE 
     WHEN f.cash_back_per = 0 
      THEN 'No Cash Back for Status' 
     WHEN c.LTGGR - e.LT_TotBonus < 0 
      THEN 'LT NGR <0' 
     WHEN d.Last_30D_RM < 0 
      THEN 'No RM Deposit in 30D' 
     WHEN e.LT_TotBonus/c.LTRM * 100 >= f.cash_back_BO_per * 100 
      THEN 'Above LT Bonus Percentage' 
     WHEN coalesce(g.CashBack_Last30D, 0) > 0 
      AND round(d.Last_30D_NGR * f.cash_back_per, 0) - coalesce(g.CashBack_Last30D, 0) < 0 
      THEN 'CashBack in 30D> Cash Back Calculated' 
     WHEN isnull(d.Last_30D_NGR) 
      THEN 'No NGR in 30D' 
     WHEN d.Last_30D_NGR < 0 
      THEN 'Negative NGR in 30D' 
     ELSE '' 
     END AS note 
FROM (
    (
     SELECT * 
     FROM players_levels 
     WHERE date_format(Date_Status, '%Y-%m') = (
       SELECT date_format(max(players_levels.Date_Status), '%Y-%m') 
       FROM players_levels 
       ) 
     GROUP BY Customers 
     ) a LEFT JOIN (
     SELECT * 
     FROM players_levels 
     WHERE date_format(Date_Status, '%Y-%m') = (
       SELECT date_format(max(players_levels.Date_Status) - INTERVAL 1 MONTH, '%Y-%m') 
       FROM players_levels 
       ) 
     ) b ON a.Customers = b.Customers 
    LEFT JOIN (
     SELECT Customers 
      ,sum(Total_Win_Loss) AS LTGGR 
      ,sum(Real_Money) AS LTRM 
      ,sum(Total_Bets) AS LTBETS 
     FROM Online_customer_activity_v2 
     GROUP BY Customers 
     ) c ON a.Customers = c.Customers 
    LEFT JOIN (
     SELECT Customers 
      ,sum(Real_Money) AS Last_30D_RM 
      ,sum(Total_Win_Loss) - sum(_Bonuses) AS Last_30D_NGR 
     FROM Online_customer_activity_v2 
     WHERE Online_customer_activity_v2.DATE >= (NOW() - INTERVAL 1 MONTH) 
     GROUP BY Customers 
     ) d ON a.Customers = d.Customers 
    LEFT JOIN (
     SELECT Account 
      ,sum(CASE 
        WHEN Method LIKE '%BONUS%' 
         AND (Method NOT LIKE '%CASHBACKBONUS%') 
         THEN Amount 
        ELSE 0 
        END) LT_Bo_No_CashB 
      ,sum(CASE 
        WHEN Method LIKE 'CASHBACKBONUS' 
         THEN Amount 
        ELSE 0 
        END) LT_CashBack 
      ,sum(CASE 
        WHEN Method LIKE '%BONUS%' 
         AND (Method NOT LIKE '%CASHBACKBONUS%') 
         THEN Amount 
        ELSE 0 
        END) + sum(CASE 
        WHEN Method LIKE 'CASHBACKBONUS' 
         THEN Amount 
        ELSE 0 
        END) AS LT_TotBonus 
     FROM `Online_dailyfinance_v2` 
     GROUP BY Account 
     ) e ON a.Customers = e.Account 
    LEFT JOIN (
     SELECT loyalty_points.status_name 
      ,loyalty_points.cash_back_per 
      ,loyalty_points.cash_back_BO_per 
     FROM loyalty_points 
     ) f ON a.status_name = f.status_name 
    LEFT JOIN (
     SELECT Account 
      ,sum(CASE 
        WHEN Method LIKE 'CASHBACKBONUS' 
         THEN Amount 
        ELSE 0 
        END) AS CashBack_Last30D 
     FROM `Online_dailyfinance_v2` 
     WHERE Online_dailyfinance_v2.DATE >= (NOW() - INTERVAL 1 MONTH) 
     GROUP BY Account 
     ) g ON a.Customers = g.Account 
    ) 
ORDER BY c.LTRM DESC 
+0

Это не служба перевода кода ... Если вы не можете использовать подзапросы, вам придется переписать, чтобы НЕ использовать их. –

+0

Хорошо. Спасибо за ваш полезный комментарий. Может быть, кто-то может любезно дать мне подсказку ... –

+0

Существует обходной путь для обработчика PHP на стороне сервера, чтобы включить поддержку JOINs, см. [Этот ответ] (http://stackoverflow.com/a/31007028/3549014) –

ответ

0

@Renaud, я приветствую ваше упорство в создании этого амбициозного запроса. Единственное, что выделяется, это то, что вам нужно делать заявления «LIKE». Я использую множество «справочных таблиц» с «TINYINT» в качестве ключа к «тексту». Поэтому у меня может быть «5» в качестве ключа к «CASHBACKBONUS» и «3» в качестве ключа к простому «БОНУСУ». Вы видите, как это может быть просто? Я надеюсь, что сценаристы-детишки с плохим отношением не прогонят мой совет/ответ, но всякий раз, когда я сталкиваюсь с ситуациями, требующими такого запроса, я обычно создаю сводные таблицы с диапазоном данных, которые мне нужны. Это не часто, но иногда это необходимо. Я даже нарушу третью нормальную форму (о, HORROR!), Если она упростит кодирование. Но я контролирую свою БД, поэтому я не знаю, можете ли вы внести эти изменения. Я занимаюсь работой с DB в течение 25 лет, поэтому возьмите его за то, что, по вашему мнению, стоит.

+0

. и да, мне тоже не нравятся необоснованные и насмешливые «ответы». Мне особенно не нравится RTFM, потому что я всегда RTFM, а руководства часто расплывчаты и неоднозначны. Пример: посмотрите на def на PDO BindValue и на BindParam. Это вызывает лодку вопросов, и все же кто-то собирается сказать «RTFM». Я буду придерживаться своего мнения об этих людях. – McAuley