Zliczenie w jednym zapytaniu ilość klinetów, klientów z wizytą oraz klientów z zamówieniem

0

Witam,

Potrzebuję najprościej zliczyć ilość klientów, klientów z wizytą oraz klientów z zamówieniem
Do pierwszego etapu czyli ilość klientów oraz ilości klientów z wizytą doszedłem tak:

 select 
count(DISTINCT c.CustomerID) as custCnt
,count(DISTINCT v.CustomerID) as custVCnt
from customers c
left join visits  v on c.CustomerID = v.CustomerID 

Problem pojawia się jak dołączam jeszcze tabelę Orders z left joinem. i próbuję zliczyć klientów z zamówieniem.

Dla zobrazowania, uproszczona struktura:
title

0

INNER JOIN zamiast LEFT JOIN i pogrupuj sobie po id klienta. Bo w tym momencie jak jeden klient ma dwie wizyty to u Ciebie liczy jako dwóch klientów.

0

Kolega Mariano się myli. Nie możesz dać INNER JOIN, ponieważ wtedy zapytanie pominie klientów bez wizyt. Grupowanie to również zły pomysł, ponieważ wtedy COUNT wyświetli ilość wierszy dla każdej grupy osobno.

SELECT 
COUNT(DISTINCT c.CustomerID) AS custCnt
,COUNT(DISTINCT v.CustomerID) AS custVCnt
,COUNT(DISTINCT o.CustomerID AS custOCnt
FROM customers c
LEFT JOIN visits  v ON c.CustomerID = v.CustomerID 
LEFT JOIN orders o ON c.CustomerID = o.CustomerID 
1

Jeżeli w Orders nie masz customerId to trzeba zrobić mniej więcej coś takiego:

 SELECT 
COUNT(DISTINCT c.CustomerID) AS custCnt
,COUNT(DISTINCT v.CustomerID) AS custVCnt
,(
     SELECT COUNT(DISTINCT c.CustomerID) 
     FROM customers c 
     INNER JOIN visits v ON v.CustomerId = c.CustomerId 
     INNER JOIN orders o ON o.VisitId = v.VisitId
) AS custOCnt
FROM customers c
LEFT JOIN visits  v ON c.CustomerID = v.CustomerID 
0

Kombinowałem, kombinowałem i wymyśliłem jeszcze coś takiego:

  SELECT 
COUNT(DISTINCT C.CustomerID) AS custCnt
,COUNT(DISTINCT V.CustomerID) AS custVCnt
,Count(DISTINCT v2.CustomerID) as custOcnt

FROM Customers C
LEFT JOIN Visits V ON C.CustomerID = V.CustomerID 
LEFT JOIN

	(SELECT CustomerID FROM Visits V  INNER JOIN Orders O on O.VisitID = V.VisitID) as V2 on V.CustomerID = V2.CustomerID
2

Ja bym poszedł bardziej w funkcje sum, wtedy można uniknąć podzapytań

SELECT
    c.customerID
    ,count(distinct c.customerID) as IloscKlientow
    ,SUM(CASE WHEN v.customerID is null then 0 else 1 end) iloscWizyt
    ,SUM(CASE WHEN o.visitID is null then 0 else 1 end) iloscZamowien
FROM 
    customers c
    LEFT JOIN visits  v ON c.CustomerID = v.CustomerID 
    LEFT JOIN orders  o ON o.VisitID = v.VisitID 
GROUP BY
    c.customerID

@Marcin.Miga ma racje ten group by po customer id jest niepotrzebny powinno być tak:

SELECT
    count(distinct c.customerID) as IloscKlientow
    ,SUM(CASE WHEN v.customerID is null then 0 else 1 end) iloscWizyt
    ,SUM(CASE WHEN o.visitID is null then 0 else 1 end) iloscZamowien
FROM 
    customers c
    LEFT JOIN visits  v ON c.CustomerID = v.CustomerID 
    LEFT JOIN orders  o ON o.VisitID = v.VisitID 
0

cześć, dzisiaj odkopałem Twoje zapytanie, ale dopiero teraz zauważyłem, że niestety nie liczy tego co powinno. Liczy ilość zamówień, wizyt, klientów. Mnie chodziło po kolei: ilość klientów, klientów z wizytami > (unikatowi), klienci z zamówieniami (unikatowi)

select
    count(customerID) IlośćKlientow
    ,sum(w) KlienciZWizytami
    ,sum(z) KlienciZZamowieniami
FROM (
    SELECT
        c.customerID
        ,max(CASE WHEN v.customerID IS NULL THEN 0 ELSE 1 END) w
        ,max(CASE WHEN o.visitID IS NULL THEN 0 ELSE 1 END) z
    FROM 
        customers c
        LEFT JOIN visits  v ON c.CustomerID = v.CustomerID 
        LEFT JOIN orders  o ON o.VisitID = v.VisitID 
    GROUP BY
        c.customerID
    ) DT

1 użytkowników online, w tym zalogowanych: 0, gości: 1