У меня есть две таблицы в SQL Server GRV
и GIV
с этими столбцами:
Запрос выглядит следующим образом:
select
GRV.ProductID, GRV.ProductName, GRV.Unit, GRV.ReceivedQTY,
GIV.ProductID, GIV.ProductName, GIV.Unit, GIV.Quantity
from
GRV
full outer join
GIV on GRV.ProductID = GIV.ProductID
Вот что я получаю:
Проблема в том, что строк красного шрифта на самом деле нет в моей таблице GIV
. Я хочу, чтобы только фактические данные таблицы объединялись как есть. GRV
с правой стороны и GIV
с левой стороны без четных рядов, обозначающих null
.
Есть ли доступный вариант? Причина, по которой мне это нужно, чтобы создать отчет о бухгалтерской книге запасов Crystal Report, где я могу показать все транзакции с полученным и выданным количеством по дате и в конце сгенерировать итоговый баланс. Пожалуйста, помогите мне в этом отношении.
P.Salmon Проблема внутреннего соединения заключается в том, что оно устраняет несоответствие значений. Как я объясняю, мне нужны все данные в виде таблицы, потому что вполне возможно, что один продукт получен, но еще не выпущен, поэтому он должен отображаться на стороне получения.
В вашем вопросе отсутствует четкий «ожидаемый результат».
Вот несколько вариантов, которые могут вам помочь.
Образец данных
create table ItemIssued
(
ProductId nvarchar(5),
Quantity int
);
insert into ItemIssued (ProductId, Quantity) values
('P0001', 100),
('P0002', 50),
('P0004', 1);
create table ItemReceived
(
ProductId nvarchar(5),
Quantity int
);
insert into ItemReceived (ProductId, Quantity) values
('P0002', 55),
('P0003', 200);
Решение 1
С null
.
select i.ProductId as ProductId,
i.Quantity as Quantity,
r.ProductId as ProductId,
r.Quantity as Quantity
from ItemIssued i
full join ItemReceived r
on r.ProductId = i.ProductId;
Решение 2
Без null
.
select coalesce(i.ProductId,'') as ProductId,
coalesce(convert(nvarchar(5), i.Quantity),'') as Quantity,
coalesce(r.ProductId,'') as ProductId,
coalesce(convert(nvarchar(5), r.Quantity),'') as Quantity
from ItemIssued i
full join ItemReceived r
on r.ProductId = i.ProductId;
Решение 3
Столы рядом друг с другом.
with ctei as
(
select row_number() over(order by i.ProductId) as RowNum,
i.ProductId,
i.Quantity
from ItemIssued i
),
cter as
(
select row_number() over(order by r.ProductId) as RowNum,
r.ProductId,
r.Quantity
from ItemReceived r
)
select ctei.ProductId,
ctei.Quantity,
cter.ProductId,
cter.Quantity
from ctei
full join cter
on cter.RowNum = ctei.RowNum;
Решение 4
Все товары с указанием количества.
with cte as
(
select i.ProductId
from ItemIssued i
union
select r.ProductId
from ItemReceived r
)
select c.ProductId,
i.Quantity,
r.Quantity
from cte c
left join ItemIssued i
on i.ProductId = c.ProductId
left join ItemReceived r
on r.ProductId = c.ProductId;
Полученные результаты
В том же порядке, что и решения.
Fiddle, чтобы увидеть его в действии.
Sander, Во-первых, большое спасибо за столь подробное объяснение решения. Решение 3 - это фактическое решение моей проблемы. Но пока я использую это с условием where, несмотря на то, что у меня есть 2 записи в Received и 1 запись в Issue, я получаю только одну запись из обеих таблиц (запись моих таблиц, созданная не вами). Не могли бы вы объяснить, почему это происходит и какие изменения необходимы для решения этой проблемы.
Я попытался воспроизвести вашу проблему (изменил некоторые образцы данных и добавил пункт where
) и предоставил решение в этой скрипте.
Простое внутреннее соединение, а не полное соединение?