Как я могу сделать этот SQL более эффективным - PullRequest
0 голосов
/ 22 ноября 2018

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

SELECT DISTINCT
    ACCOUNTNUM,
    FIRSTNAME AS NAME, 
    LASTNAME AS SURNAME, 
    (PHONE + ' ' + CELLULARPHONE) AS PHONENUM, 
    EMAIL,
    (SELECT TOP 1 CREATEDDATE 
     FROM RBOTRANSACTIONTABLE 
     WHERE CUSTACCOUNT = ACCOUNTNUM 
     ORDER BY CREATEDDATE DESC) AS LASTVISIT,  -- LAST VISIT, 
    (SELECT COUNT(TRANSACTIONID) 
     FROM RBOTRANSACTIONTABLE 
     WHERE CUSTACCOUNT = ACCOUNTNUM) AS TOTALVISITS, -- TOTAL VISITS, 
    (SELECT SUM(PAYMENTAMOUNT) 
     FROM RBOTRANSACTIONTABLE 
     WHERE CUSTACCOUNT = ACCOUNTNUM) AS TOTALSALES, -- TOTAL SALES,  
    (SELECT SUM(DISCAMOUNT) 
     FROM RBOTRANSACTIONTABLE 
     WHERE CUSTACCOUNT = ACCOUNTNUM) AS DISCOUNT
FROM 
    CUSTOMER 
LEFT OUTER JOIN 
    RBOTRANSACTIONTABLE ON CUSTACCOUNT = ACCOUNTNUM

Я знаю, что если я использую какое-то соединение, я неНеобязательно каждый раз повторять FROM RBOTRANSACTIONTABLE (код после Email столбца).Приведенный выше код отлично подходит для моих требований, но я знаю, что в моих знаниях пропущены пробелы, я просто не знаю что .

Я ищу подробные ответы опочему вышеупомянутое решение не рекомендуется и почему ваше решение.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Тим, безусловно, хороший способ переписать запрос.Но вы также можете сделать свою версию более эффективной, избавившись от count(distinct) и внешнего соединения:

SELECT ACCOUNTNUM,
       FIRSTNAME AS NAME, 
       LASTNAME AS SURNAME, 
       (PHONE + ' ' + CELLULARPHONE) AS PHONENUM, 
       EMAIL,
       (SELECT TOP 1 CREATEDDATE FROM RBOTRANSACTIONTABLE WHERE CUSTACCOUNT = ACCOUNTNUM ORDER BY CREATEDDATE DESC) AS LASTVISIT,  -- LAST VISIT, 
       (SELECT COUNT(TRANSACTIONID) FROM RBOTRANSACTIONTABLE WHERE CUSTACCOUNT = ACCOUNTNUM) AS TOTALVISITS, -- TOTAL VISITS, 
       (SELECT SUM(PAYMENTAMOUNT) FROM RBOTRANSACTIONTABLE WHERE CUSTACCOUNT = ACCOUNTNUM) AS TOTALSALES, -- TOTAL SALES,  
       (SELECT SUM(DISCAMOUNT) FROM RBOTRANSACTIONTABLE WHERE CUSTACCOUNT = ACCOUNTNUM) AS DISCOUNT
FROM CUSTOMER c;

С правильными индексами это может даже иметь лучшую производительность, чем group by / joinверсия.

0 голосов
/ 22 ноября 2018

Вы можете переписать свой запрос как объединение с подзапросом, который находит агрегаты:

SELECT
    c.ACCOUNTNUM,
    c.FIRSTNAME AS NAME,
    c.LASTNAME AS SURNAME,
    (c.PHONE + ' ' + c.CELLULARPHONE) AS PHONENUM,
    c.EMAIL,
    a.LASTVISIT,
    COALESCE(a.TOTALVISITS, 0) AS TOTALVISITS,
    COALESCE(a.TOTALSALES, 0) AS TOTALSALES,
    COALESCE(a.DISCOUNT, 0) AS DISCOUNT
FROM CUSTOMER c
LEFT JOIN
(
    SELECT
        CUSTACCOUNT,
        MAX(CREATEDDATE) AS LASTVISIT,
        COUNT(TRANSACTIONID) AS TOTALVISITS,
        SUM(PAYMENTAMOUNT) AS TOTALSALES,
        SUM(DISCAMOUNT) AS DISCOUNT
    FROM RBOTRANSACTIONTABLE
    GROUP BY CUSTACCOUNT
) a
    ON c.ACCOUNTNUM = a.CUSTACCOUNT;

Вы должны всегда использовать правильные псевдонимы при обращении к столбцам в предложении SELECT.

...