SQL Выберите Query для извлечения данных из 2 таблиц -show 0, а не в table1 или table 2 - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть 2 таблицы, как показано ниже

TABLE_1

Date         Code   Time   Weight
01-09-2018      1   AM        100
01-09-2018      1   AM        120
01-09-2018      2   AM         80
01-09-2018      4   AM        135
02-09-2018      1   AM         50
02-09-2018      2   AM        110
02-09-2018      3   AM        115


TABLE_2

Date         Code   Time    Weight
01-09-2018      1   PM        110
01-09-2018      2   PM        115
01-09-2018      3   PM        125
01-09-2018      4   PM        100
02-09-2018      1   PM        130
02-09-2018      3   PM         50
02-09-2018      1   PM         75

Желаемый результат

Date         Code    AM    PM
01-09-2018      1   220   110
01-09-2018      2    80   115
01-09-2018      3     0   125
01-09-2018      4   135   100
02-09-2018      1    50   205
02-09-2018      2   110     0
02-09-2018      3   115    50

Мне нужен MS-SQL Select Query для этого вывода.

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Может быть легче понять, сгруппировав сначала:

select 
  Coalesce(t1.[date], t2.[date]) as [date],
  Coalesce(t1.code, t2.code) as code,
  Coalesce(Sum_am, 0) as [am],
  Coalesce(Sum_pm, 0) as [pm]
From
  (Select [date], code, sum(weight) as sum_am from table1 group by [date], code) t1
  Full outer join 
  (Select [date], code, sum(weight) as sum_pm from table2 group by [date], code) t2
  on t1.code =t2.code and t1.[date]=t2.[date]
0 голосов
/ 16 сентября 2018

Это классический пример сводной таблицы.Современные СУБД выполняют всю работу за вас в одном утверждении (см. Ниже).

Во-первых, нет причин разбивать данные на две таблицы на основе различия AM / PM.Это не очень хорошая идея.Даже если это упрощенная версия большого приложения с массивными данными, требующими многораздельных таблиц, вы должны настроить это так, чтобы запросы могли выполняться к одной главной таблице.

Итак, давайте поместим все данные в таблицу1.

insert into t1 values('2018-09-01',1,'AM',100),
('2018-09-01',1,'AM',120),
('2018-09-01',2,'AM',80),
('2018-09-02',1,'AM',50),
('2018-09-02',2,'AM',110),
('2018-09-01',1,'PM',110),
('2018-09-01',2,'PM',115);

Теперь давайте google для синтаксиса команды PIVOT.(Это будет конечно отличаться для других поставщиков; я не думаю, что это является частью стандарта SQL, по крайней мере, как обычно реализуется.)

Presto!

select * FROM t1 
PIVOT (SUM(weight) FOR [time] in ([AM], [PM])) AS tz;

date1   code    AM  PM
01/09/2018 00:00:00 1   220 110
02/09/2018 00:00:00 1   50<br>
01/09/2018 00:00:00 2   80  115
02/09/2018 00:00:00 2   110 

(Вы можете использовать это как подзапрос и COALESCE, если вам действительно нужно заменить пробелы в PM нулями. Кроме того, если вам действительно нужны две таблицы, используйте подзапрос, чтобы просто UNION их вместе перед использованием PIVOT.)

0 голосов
/ 16 сентября 2018

использовать левое соединение и условное агрегирование

select t1.date, t1.code, 
       sum(case when t1.Time='AM' then t1.weight else 0 end ) as AM,
       sum(case when t2.Time='PM' then t2.weight else 0 end ) as PM
  from table1 t1 lef join table2 t2 on t1.code =t2.code and t1.date=t2.date
 group by t1.date, t1.code

Или то же самое можно написать с помощью cte

with t1 as

(select date,code,time,sum(weight) as w from table1
group by date,code
),
t2 as
(
select date,code,time,sum(weight) as w from table2
group by date,code
) select t1.date,t1.code, max(case when t1.time='AM' then t1.w end)  as AM,
         max(case when t2.time='PM' then t1.w end) as PM
          from t1 left join t2 on t1.code=t2.code and t1.date=t2.date
           group by t1.date,t1.code

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=e7e0bf11006a2b04602ca9f0a4071ed0

...