Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопрос по соединению таблиц  [new]
mike_dav
Member

Откуда:
Сообщений: 24
Доброго времени суток всем.
Подскажите, пожалуйста, как из трех таблиц можно получить нужный результат. Таблицы следующие:
declare @Joining table
(	[JoiningId] [int] NOT NULL,
	[Date] [datetime] NULL,
	[Number] [int] NULL)

declare @Income table
(	[IncomeId] [int] NOT NULL,
	[JoiningId] [int] NULL,
	[CostId] [int] NULL,
	[Summa] [money] NULL)

declare @Expense table	
	(
	[ExpenseId] [int] NULL,
	[JoiningId] [int] NULL,
	[CostId] [int] NULL,
	[Summa] [money] NULL )

insert into @Joining  ([JoiningId], [Date], [Number])
values (1, '20120101', 1)
insert into @Joining  ([JoiningId], [Date], [Number])
values (2, '20120102', 2)
insert into @Joining  ([JoiningId], [Date], [Number])
values (3, '20120103', 3)

	
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (1,1,2, 100)
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (2,1,3, 200)	
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (3,1,1, 300)	
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (4,2,1, 500)	

insert into @Expense ([ExpenseId], [JoiningId], [CostId], [Summa])	
values (1,1,7, 1000)
insert into @Expense ([ExpenseId], [JoiningId], [CostId], [Summa])	
values (2,2,5, 3000)
insert into @Expense ([ExpenseId], [JoiningId], [CostId], [Summa])	
values (3,2,4, 2000)
	


запрос следующий:

  Select
   jo.JoiningId
  ,jo.Date
  ,jo.Number
  ,Inc.IncomeId
  ,inc.Summa as SummaInc 
  ,ex.ExpenseId
  ,ex.Summa as SummaEx

  from @Joining jo
  full Outer join @Income inc  on inc.JoiningId = jo.JoiningId  
  full Outer join @Expense ex on ex.JoiningId = jo.JoiningId  


выводит результат такой:

JoiningIdDateNumberIncomeIdSummaIncExpenseIdSummaEx
12012-01-01 00:00:00.00011100.0011000.00
12012-01-01 00:00:00.00012200.0011000.00
12012-01-01 00:00:00.00013300.0011000.00
22012-01-02 00:00:00.00024500.0023000.00
22012-01-02 00:00:00.00024500.0032000.00
32012-01-03 00:00:00.0003NULLNULLNULLNULL


а нужно добиться такого результата:
JoiningIdDateNumberIncomeIdSummaIncExpenseIdSummaEx
12012-01-01 00:00:00.00011100.0011000.00
12012-01-01 00:00:00.00012200.00NULLNULL
12012-01-01 00:00:00.00013300.00NULLNULL
22012-01-02 00:00:00.00024500.0023000.00
22012-01-02 00:00:00.0002NULLNULL32000.00
32012-01-03 00:00:00.0003NULLNULLNULLNULL


По-сути, если сформулировать грубо, то нужно исключить дублирующие записи, каким -то образом "наложить" данные друг на друга. Подскажите в каком направлении смотреть. За примеры и ссылки на похожие примеры буду благодарен.
4 дек 12, 13:27    [13574810]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
Добрый Э - Эх
Guest
case по row_number-у тебе в помощь
4 дек 12, 13:30    [13574834]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
так зашёл
Guest
Добрый Э - Эх
case по row_number-у тебе в помощь


как-то так например:

select
     JoiningId
    ,Date
    ,Number
    ,case when I_R=1 then IncomeId end IncomeId
    ,case when I_R=1 then SummaInc end SummaInc 
    ,case when E_R=1 then ExpenseId end ExpenseId
    ,case when E_R=1 then SummaEx end SummaEx
from(
  Select
     jo.JoiningId
    ,jo.Date
    ,jo.Number
    ,Inc.IncomeId
    ,inc.Summa as SummaInc 
    ,ex.ExpenseId
    ,ex.Summa as SummaEx
    ,rank()over(partition by Inc.IncomeId order by ex.ExpenseId)I_R
    ,rank()over(partition by ex.ExpenseId order by Inc.IncomeId)E_R
  from @Joining jo
  full Outer join @Income inc  on inc.JoiningId = jo.JoiningId  
  full Outer join @Expense ex on ex.JoiningId = jo.JoiningId  
)T
Order By 1, 2
4 дек 12, 13:46    [13574967]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
mike_dav
Member

Откуда:
Сообщений: 24
спасибо огромное, кажется то, что нужно!
4 дек 12, 13:51    [13575016]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
mike_dav
Member

Откуда:
Сообщений: 24
"так зашел" - можешь написать мне в личку, хотел поблагодарить.
4 дек 12, 13:52    [13575032]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
Добрый Э - Эх
Guest
так зашёл,

Я бы всё же остановил свой выбор на ROW_NUMBER, ибо в рамках недетерминированной сортировки на строках-дубликатах RANK | DENSE_RANK не дадут желаемого автором топика результата...
Для примера:
with t (n) as (select 1 
 union all select 1
 union all select 2
 union all select 2
 union all select 3
          )

select n
     , row_number() over(order by n) as r_n
     , rank() over(order by n) as r
     , dense_rank() over(order by n) as d_r
  from t

он-лайн проверка на sqlfiddle.com
4 дек 12, 15:59    [13576322]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по соединению таблиц  [new]
mike_dav
Member

Откуда:
Сообщений: 24
Добрый Э - Эх,

Да вы совершенно правы, в этом случае будет лучше использовать row_number.
Хотел еще немного развить эту тему. Немного поменяю исходные данные:

declare @Joining table
(	[JoiningId] [int] NOT NULL,
	[Date] [datetime] NULL,
	[Number] [int] NULL)

declare @Income table
(	[IncomeId] [int] NOT NULL,
	[JoiningId] [int] NULL,
	[CostId] [int] NULL,
	[Summa] [money] NULL)

declare @Expense table	
	(
	[ExpenseId] [int] NULL,
	[JoiningId] [int] NULL,
	[CostId] [int] NULL,
	[Summa] [money] NULL )

insert into @Joining  ([JoiningId], [Date], [Number])
values (1, '20120101', 1)
insert into @Joining  ([JoiningId], [Date], [Number])
values (2, '20120102', 2)
insert into @Joining  ([JoiningId], [Date], [Number])
values (3, '20120103', 3)

	
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (1,2,2, 100)
insert into @Income ([IncomeId], [JoiningId], [CostId], [Summa])	
values (2,2,3, 200)	

insert into @Expense ([ExpenseId], [JoiningId], [CostId], [Summa])	
values (1,2,5, 3000)
insert into @Expense ([ExpenseId], [JoiningId], [CostId], [Summa])	
values (2,2,4, 2000)


Запрос такой:

select
     JoiningId
    ,Date
    ,Number
    ,case when I_R=1 then IncomeId end IncomeId
    ,case when I_R=1 then SummaInc end SummaInc 
    ,case when E_R=1 then ExpenseId end ExpenseId
    ,case when E_R=1 then SummaEx end SummaEx
from(
  Select
     jo.JoiningId
    ,jo.Date
    ,jo.Number
    ,Inc.IncomeId
    ,inc.Summa as SummaInc 
    ,ex.ExpenseId
    ,ex.Summa as SummaEx
    ,row_number() over(partition by Inc.IncomeId order by ex.ExpenseId)I_R
    ,row_number()over(partition by ex.ExpenseId order by Inc.IncomeId)E_R
  from @Joining jo
  full Outer join @Income inc  on inc.JoiningId = jo.JoiningId  
  full Outer join @Expense ex on ex.JoiningId = jo.JoiningId  
)T
Order By 1, 2


Выдает результат:
JoiningIdDateNumberIncomeIdSummaIncExpenseIdSummaEx
12012-01-01 00:00:00.0001NULLNULLNULLNULL
22012-01-02 00:00:00.00021100.0013000.00
22012-01-02 00:00:00.00022200.00NULLNULL
22012-01-02 00:00:00.0002NULLNULL22000.00
22012-01-02 00:00:00.0002NULLNULLNULLNULL
32012-01-03 00:00:00.0003NULLNULLNULLNULL


Вопрос в следующем можно ли одним запросом вывести следующий результат?

JoiningIdDateNumberIncomeIdSummaIncExpenseIdSummaEx
12012-01-01 00:00:00.0001NULLNULLNULLNULL
22012-01-02 00:00:00.00021100.0013000.00
22012-01-02 00:00:00.00022200.0022000.00
32012-01-03 00:00:00.0003NULLNULLNULLNULL


Ограничение в один запрос связано с тем, что потом на его базе необходимо сделать вьюху. MSSQL Server 2008.
13 дек 12, 10:42    [13623912]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить