2016-10-27 3 views
3

Я пытался полностью понять, присоединяется на следующем примере я сконструированной в сервере SQLПонимание соединяется с примером

DECLARE @tablePlace TABLE (ID INT, someplace varchar(10)) 
DECLARE @tableType TABLE (ID INT, sometype varchar(10)) 
DECLARE @tableOrders TABLE (ID INT, type int , place int) 

INSERT INTO @tablePlace (ID, someplace) values (1,'Place A') 
INSERT INTO @tablePlace (ID, someplace) values (2,'Place B') 

INSERT INTO @tableType (ID, sometype) VALUES (1,'Type 1') 
INSERT INTO @tableType (ID, sometype) VALUES (2,'Type 2') 
INSERT INTO @tableType (ID, sometype) VALUES (3,'Type 3') 
INSERT INTO @tableType (ID, sometype) VALUES (4,'Type 4') 

INSERT INTO @tableOrders (ID, place, type) values (1 , 1 , 1) -- PLACE A TYPE 1 
INSERT INTO @tableOrders (ID, place, type) values (2 , 1 , 2) -- PLACE A TYPE 2 
INSERT INTO @tableOrders (ID, place, type) values (3 , 2 , 2) -- PLACE B TYPE 2 

Теперь то, что я пытаюсь сделать, это связать три таблицы, чтобы получить следующее результат

╔═════════╦════════╦═══════╗ 
║ PLACE ║ TYPE ║ COUNT ║ 
╠═════════╬════════╬═══════╣ 
║ PLACE A ║ TYPE 1 ║  1 ║ 
║ PLACE A ║ TYPE 2 ║  1 ║ 
║ PLACE A ║ TYPE 3 ║  0 ║ 
║ PLACE A ║ TYPE 4 ║  0 ║ 
║ PLACE B ║ TYPE 1 ║  0 ║ 
║ PLACE B ║ TYPE 2 ║  1 ║ 
║ PLACE B ║ TYPE 3 ║  0 ║ 
║ PLACE B ║ TYPE 4 ║  0 ║ 
╚═════════╩════════╩═══════╝ 

Так что я пытаюсь сделать, это связать два места и показать количество каждого типа в соответствии с записями, извлекаемых из @tableorders таблицы.


Мой запрос до сих пор:

SELECT place.someplace, 
     type.sometype, 
     Count(*) AS count 
FROM @tableOrders orders 
     INNER JOIN @tableplace place 
       ON orders.place = place.id 
     INNER JOIN @tabletype type 
       ON place.id = type.id 
GROUP BY someplace, 
      sometype 
ORDER BY someplace, 
      sometype 

Может кто-то пожалуйста, объясните логику, я должен следовать, чтобы достичь своих желаемых результатов? Заранее спасибо!

ответ

3

Вы хотите получить перекрестное соединение для генерации строк. Тогда left join (или коррелируется подзапрос), чтобы получить получить значение:

select p.someplace, t.sometype, count(o.id) as count 
from @tableplace p cross join 
    @tabletype t left join 
    @tableOrders o 
    on o.type = t.id and o.place = p.id 
group by p.someplace, t.sometype 
order by p.someplace, t.sometype; 
1

Использование CROSS JOIN для генерации MxN таблицы (соединяющая все места с типами), а затем LEFT JOIN к таблице заказов, чтобы получить счетчик для каждой пары (someplace, sometype):

select tp.someplace, tt.sometype, count(to.id) as count 
from @tablePlace tp 
cross join @tableType tt 
left join @tableOrders to on 
    to.place = tp.id and to.type = tt.id 
group by tp.someplace, tt.sometype 
order by tp.someplace, tt.sometype 
2

Попробуйте это:

SELECT place.someplace, [type].sometype , T.cnt 
FROM @tablePlace place 
CROSS join @tabletype [type] 
OUTER APPLY 
( SELECT COUNT(1) cnt 
    FROM @tableOrders tableOrders 
    WHERE tableOrders.place=place.ID AND tableOrders.[type] = [type].ID 
)T 
ORDER BY someplace,sometype 

ВЫВОДА:

Place A Type 1 1 
Place A Type 2 1 
Place A Type 3 0 
Place A Type 4 0 
Place B Type 1 0 
Place B Type 2 1 
Place B Type 3 0 
Place B Type 4 0 
0

Попробуйте это:

SELECT A.someplace,B.sometype,COUNT(C.ID) count_val FROM @tablePlace A CROSS JOIN 
@tableType B LEFT JOIN @tableOrders C ON C.place = A.ID AND C.type = B.ID 
GROUP BY someplace,sometype 

Надеется, что это помогает. :)

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