2016-12-15 4 views
0

Мне нужен SQL-запрос, чтобы возвращать строку для каждого месяца в 2015 и 2016 годах для каждой компании, которая платит взносы. Полученный набор данных покажет, в какие месяцы компания не платила взносы за нулевое значение. Проблема в том, что если они не будут платить взносы, у них не будет записи в базе данных, поэтому никакая строка не появится за месяц. Вот запрос:Показать строку в серии, даже если данные отсутствуют в таблице

SELECT 
case when n.co_id <>'' then n.co_id else n.ID end ID 
,su.CONTINUOUS_SINCE 
,n.COMPANY 
,a.EFFECTIVE_DATE 
, a.AMOUNT 


FROM dbo.Name n 
LEFT OUTER JOIN dbo.Activity a ON n.ID = a.ID 
inner JOIN dbo.Loc_Info l ON n.ID = l.ID 
inner JOIN dbo.Segment_Categories s ON l.CURRENT_SEGMENT = s.CODE 
inner JOIN dbo.Subscriptions su on su.id=n.id 

WHERE   a.PRODUCT_CODE='rental' and n.MEMBER_TYPE in ('rb','rl') and a.EFFECTIVE_DATE Between '2015-07-01' And GetDate() AND a.ACTIVITY_TYPE='dues' 
order by case when n.co_id <>'' then n.co_id else n.ID end, EFFECTIVE_DATE asc 

Если компания заплатила каждый месяц она работает хорошо, но дело в том, чтобы найти компании, которые не выплатили так предположим, компания XYZ выплачивается каждый месяц в 2015 году, за исключением июня мне нужно строка за июнь для компании XYZ, которая имеет значение NULL или нулевой или какой-либо другой показатель, что они пропустили платеж. В настоящее время строка просто пропущена, потому что данных нет, и трудно найти недостающую строку из тысяч или строк.

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

+0

Какая версия SQL Server? –

+0

Извините. SQL 2012. В частности, 12.0.2000.8 – ekim110575

ответ

0

1) Сформировать все месяцы от 1 до 12 с рекурсивным cte.

2) Получите все месяцы и комбинации компаний с cross join.

3) left join в этом результирующем наборе, чтобы показывать отсутствующие месяцы.

with months as (select 1 mth 
       union all 
       select mth+1 from months where mth<12) 
,yearmonthscompanies as (select * 
         from months m 
         cross join (select 2015 yr union all select 2016 yr) y 
         cross join (select distinct id,co_id,company from name) c 
         ) 
SELECT 
case when ymc.co_id <>'' then ymc.co_id else ymc.ID end ID 
,su.CONTINUOUS_SINCE 
,ymc.COMPANY 
,coalesce(a.effective_date,datefromparts(ymc.yr,ymc.mth,1)) as effective_date 
,coalesce(a.AMOUNT,0) amount 
FROM yearmonthscompanies ymc 
LEFT JOIN dbo.Name n ON n.co_id=ymc.co_id and n.id=ymc.id and n.company=ymc.company 
LEFT JOIN dbo.Activity a ON n.ID = a.ID and a.PRODUCT_CODE='rental' 
and n.MEMBER_TYPE in ('rb','rl') and a.EFFECTIVE_DATE Between '2015-07-01' and GetDate() 
and a.ACTIVITY_TYPE='dues' 
and year(a.effective_date) = ymc.yr and month(a.effective_date) = ymc.mth 
inner JOIN dbo.Loc_Info l ON n.ID = l.ID 
inner JOIN dbo.Segment_Categories s ON l.CURRENT_SEGMENT = s.CODE 
inner JOIN dbo.Subscriptions su on su.id=n.id 
order by case when ymc.co_id <>'' then ymc.co_id else ymc.ID end 
,effective_date 
+0

Спасибо, ваше решение сработало. Я использовал несколько крестов несколько раз в прошлом и был не слишком удобен с ними. Я сделал несколько трюков по вашему запросу, но только потому, что у вас не было всех подробностей, когда вы его написали, но мне нужно было добавить только одну строку кода, и она работала, как прелесть, и решила мою проблему. – ekim110575

1

Вы можете создать фиктивную таблицу для месяцев, покинул присоединиться к dbo.Activity к нему, таким образом, вы получите все месяцы, а затем присоединиться, что dbo.Name

+0

Спасибо, это решение действительно работало, а также решение vkp. Я пошел с ним, потому что это было меньше кода в целом и выполнялось немного быстрее, однако ваше решение также было эффективным. Спасибо за помощь. – ekim110575

Смежные вопросы