Как выбрать даже несуществующие значения - PullRequest
2 голосов
/ 26 июля 2010

Я использую SQL-Server 2005

У меня есть две таблицы: Пользователи и Заказы.У каждого пользователя может быть много заказов.Таблицы подключены через userID.Заказы имеют столбец с датой (когда заказ был сделан).У пользователей есть столбец registrationSite (который является партнерским сайтом за пользователем и всеми его заказами).

Я хочу выбрать сумму заказов в день и сайт, поэтому , даже если сайт не продан илиПользователь зарегистрировался. У меня будет 0 в качестве суммы.

это текущий запрос, который пропускает выделенную часть.

select sum(orderSum)*40/100-0.17,count(*),
registrationSite,
dateadd(dd,datediff(dd,0,cu.date),0)
from Users cu 
inner join Orders cp 
on cu.userID=cp.userID
group by dateadd(dd,datediff(dd,0,cu.date),0),registrationSite
order by dateadd(dd,datediff(dd,0,cu.date),0),registrationSite

Ответы [ 2 ]

3 голосов
/ 26 июля 2010

Используйте LEFT OUTER JOIN вместо INNER JOIN ..

from Users cu 
inner join Orders cp 

должно стать

from Users cu 
left outer join Orders cp 

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


обновление

вам нужносоздайте таблицу tally с диапазонами дат ( дней ) и left outer join для этого ..

посмотрите здесь: Как получить таблицу издаты между x и y в sql server 2005

1 голос
/ 26 июля 2010

Если вы используете SQL 2005 или более позднюю версию, вы можете создать свою таблицу Calendar на лету, используя выражение общей таблицы. В исходном сообщении вы выполняете математику даты на cu.date, но псевдоним cu представляет таблицу Users, а не таблицу Orders. Я предполагаю, что это должно было быть cp.date? То есть, ваше описание говорит о датах заказа, но ваш SQL использует дату в таблице Users.

With OrderDateBoundaries As
    (
    Select Cast(DateDiff(d,0,Min([Date]))) As MinDate
        , Cast(DateDiff(d,0,Max([Date]))) As MaxDate
    From Orders
    )
    , Calendar As
    (
    Select MinDate As [Date]
    From OrderDateBoundaries
    Union All
    Select DateAdd(d, 1, [Date])
    From Calendar
    Where [Date] <= DateAdd(d, 1, (
                                    Select MaxDate
                                    From OrderDateBoundaries
                                    ))
    )
Select Calendar.[Date]
    , Coalesce(Sum(O.ordersum) * 40 / 100 - 0.17,0) As OrderSum
    , Count(*)
    , RegistrationSite
From Calendar
        Left Join (Users As U
            Join Orders As O
                On O.userId = U.UserId)
             On Cast(DateDiff(d, 0, O.OrderDate) As datetime) =Calendar.Date
Group By Calendar.[Date], registrationsite
Option(MaxRecursion 0);

Если вы хотите присоединиться к Users.Date, то сделать это просто. Кроме того, неясно, из какой таблицы хранится таблица ordersum.

With DateBoundaries As
    (
    Select Cast(DateDiff(d,0,Min([Date]))) As MinDate
        , Cast(DateDiff(d,0,Max([Date]))) As MaxDate
    From Users
    )
    , Calendar As
    (
    Select MinDate As [Date]
    From DateBoundaries
    Union All
    Select DateAdd(d, 1, [Date])
    From Calendar
    Where [Date] <= DateAdd(d, 1, (
                                    Select MaxDate
                                    From DateBoundaries
                                    ))
    )
Select Calendar.[Date]
    , Coalesce(Sum(O.ordersum) * 40 / 100 - 0.17,0) As OrderSum
    , Count(*)
    , RegistrationSite
From Calendar
        Left Join (Users As U
            Join Orders As O
                On O.userId = U.UserId)
             On Cast(DateDiff(d,0,U.Date) As datetime) =Calendar.Date
Group By Calendar.[Date], RegistrationSite
Option(MaxRecursion 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...