Вычитание результатов из двух запросов / подзапросов - PullRequest
1 голос
/ 25 июня 2019

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

В настоящее время у меня есть таблица, содержащая всю информацию о заказе клиента, как созданную, так и отмененную. Каждый заказ клиента имеет уникальный номер заказа, место, где он был продан, дату создания и дату отмены. Если заказ клиента все еще действителен, тогда дата отмены будет нулевой или "//". Если заказ клиента отменен, то у него будет дата отмены. В качестве некоторой дополнительной информации заказ клиента может быть создан в январе 2019 года и отменен в июле, августе или декабре и т. Д. Я хотел бы получить чистые заказы клиентов за все месяцы, выполняя валовые заказы клиентов за месяц - отмененный клиент заказы за этот месяц и для определенного местоположения = чистые заказы клиентов за этот месяц для этого местоположения.

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

Первый запрос с действительными заказами клиентов с именем cust_valid (упрощенно):

SELECT cust_ords.[SaleLoc], cust_ords.[OrderNum], cust_ords.[CreationDate], cust_ords.[CancelDate]
FROM cust_ords
WHERE cust_ords.[CancelDate] = "" OR  cust_ords.[CancelDate] = "//";

Второй запрос с отмененными заказами клиентов с именем cust_cancelled (упрощенный):

SELECT cust_ords.[SaleLoc], cust_ords.[OrderNum], cust_ords.[CreationDate], cust_ords.[CancelDate]
FROM cust_ords
WHERE cust_ords.[CancelDate] <> "" OR  cust_ords.[CancelDate] <> "//";

Наконец, кросс-таблица между ними:

TRANSFORM Count(cust_valid.[OrderNum]) AS [NetOrderCount]
SELECT cust_valid.[SaleLoc]
FROM cust_valid LEFT JOIN cust_cancelled ON cust_valid.[CreationDate] = cust_cancelled.[CancelDate]   
WHERE cust_valid.[CreationDate] = cust_cancelled.[CancelDate]
GROUP BY cust_ords.[SaleLoc]
PIVOT cust_valid.[CreationDate]; 

В этом смысле я пытаюсь получить (посчитать) чистые заказы клиентов (общее количество созданных за месяц - что было отменено в этом месяце) для каждого заданного местоположения и отобразить результаты за месяц (в основном имена столбцов должны быть год и месяц). Так, например, если у меня есть 10 заказов клиентов в январе, 5 в феврале и 15 в марте, если 3 из них в январе будут отменены в марте, то я хотел бы считать за месяц с 15 по 3 марта, таким образом, в конечном итоге с 10 января, 5 февраля, 12 марта.

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Спасибо @ Сорен Конгстад ​​за полезные объяснения. Я изменил / исправил код, чтобы получить необходимые результаты:

SELECT CustOrders.[Grupp namn], Format(IIf(CustOrders.[DatAnnulCde]="/  /",CustOrders.[DatCreatCde],CustOrders.[DatAnnulCde]),"yyyy-mm") AS year_month, 
Sum(IIf(IsNull(CustOrders.DatCreatCde),0,1)) AS GrossOrders, Sum(IIf(CustOrders.DatAnnulCde<>"/  /",1,0)) AS CancelledOrders, 
Sum(IIf(IsNull(CustOrders.DatCreatCde),0,1)) - Sum(IIf(CustOrders.DatAnnulCde<>"/  /",1,0)) AS NetOrders
FROM CustOrders
WHERE CustOrders.[CarType] = "Renault PC" And CustOrders.[DatCreatCde] >= Format(Year(Now())&"-01-01","yyyy-mm-dd")
GROUP BY CustOrders.[Grupp namn], Format(IIf(CustOrders.[DatAnnulCde]="/  /",CustOrders.[DatCreatCde],CustOrders.[DatAnnulCde]),"yyyy-mm");

Поля имеют разные имена, чем в исходных примерах DatAnnulCde = CancelDate DatCreatCde = CreationDate

0 голосов
/ 25 июня 2019

Прежде всего, вы говорите, что заказ действителен, если дата отмены равна нулю или //, однако вы проверяете:

ГДЕ cust_ords. [CancelDate] = "" ИЛИ cust_ords. [CancelDate] = "//";

Для проверки на нулевое использование [CancelDate] имеет значение null, или сокращение от теста до ISNULL ([CancelDate], '//') = '//'

Во-вторых, во втором запросе вы проверяете отмененные заказы с

ГДЕ cust_ords. [CancelDate] <> "" ИЛИ cust_ords. [CancelDate] <> "//";

Это не отрицание вашего теста на отмененные заказы!

 !(A or B) => !A and !B

Так что вы должны использовать

ГДЕ cust_ords. [CancelDate] <> "" и cust_ords. [CancelDate] <> "//";

Вернее, ISNULL (cust_ords. [CancelDate], '//')! = '//'

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

SELECT
     cust_valid.[SaleLoc]
     ,  Format(
        iif(isnull(cust_ords.[CancelDate],'//')='//'
                ,cust_ords.[CreationDate]
                ,cust_ords.[CancelDate]
                ,'MMMM yy') Mnth
     , sum(iif(isnull(cust_ords.[CancelDate],'//'='//',1,0)) ValidOrders 
     , sum(iif(isnull(cust_ords.[CancelDate],'//'='//',0,1)) CancelledOrders 
     , sum(iif(isnull(cust_ords.[CancelDate],'//'='//',1,0))  
        - sum(iif(isnull(cust_ords.[CancelDate],'//'='//',0,1)) NetOrderCount 
FROM
       cust_ords
group by
     cust_valid.[SaleLoc]
     ,  Format(
        iif(isnull(cust_ords.[CancelDate],'//')='//'
                ,cust_ords.[CreationDate]
                ,cust_ords.[CancelDate]
                ,'MMMM yy')

Это должно дать вам основные данные, полезные для поворота, по крайней мере, в SQL Server

...