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

Откуда:
Сообщений: 12
есть таблица
historyID | ID | Organisation | DateOfCorrection(int) | value
_________________________________________________
1 | 1 | 15 | 34574562563456 | "500"
2 | 2 | 15 | 34574562563456 | "600"
3 | 15 | 18 | 45734563473434 | "*"
4 | 16 | 18 | 45734563473434 | "*"
5 | 1 | 15 | 64563456256262 | "555"
6 | 2 | 15 | 64563456256262 | "600"
7 | 3 | 15 | 64563456256262 | "700"
............................................................................
134 | 2 | 15 | 78456745684568 | "600"
135 | 3 | 15 | 78456745684568 | "777"
............................................................................

В общем смысл такой, у организации(Organisation) есть телефоны (ID), которые могут меняться, добавляться или удалятся. При любом изменении хотя бы одного телефона у организации.
На момент времени 34574562563456 у организации "15" было 2 телефона, в момент времени 64563456256262 у организации "15" было 3 телефона, в момент времени 78456745684568 стало 2 телефона.

Необходим запрос (процедура) в которой параметром будет @organisation и @dateofcorrection
В результате необходимо получить данные (value) на момент времени @dateofcorrection и прошлые данные в одной строке.

value | oldValue (при @organisation=15 и @dateofcorrection=64563456256262)
null | 555
600 | 600
null | 700

value | oldValue (при @organisation=15 и @dateofcorrection=78456745684568)
555 | 500
600 | 600
777 | 700


Проблема именно в том чтобы количество строк на выходе было таким сколько было телефонов либо до либо после но максимальным. То есть если было 3 стало 2 то строк 3, если было 2 стало 4 то строк 4.


Что делаю сейчас:
select
table.value as value,

oldtable.value as oldValue

from table
FULL JOIN table as oldTable
on table.Organisation=oldTable.Organisation
AND table.ID=oldTable.ID
WHERE (table.Organisation=@organisation OR oldTable.Organisation=@organisation)
AND (table.DateOfCorrection=(select max(DateOfCorrection) from table as q where q.DateOfCorrection<@dateofcorrection))
// типо дата на уровень ниже


Но это не работает...
9 авг 11, 01:08    [11088894]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
klivzez
Member

Откуда:
Сообщений: 12
вот тут немного неправильно написал предполагаемый результат

value | oldValue (при @organisation=15 и @dateofcorrection=64563456256262)
555 | 500
600 | 600
700 | null

value | oldValue (при @organisation=15 и @dateofcorrection=78456745684568)
null | 555
600 | 600
777 | 700
9 авг 11, 01:12    [11088897]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
klivzez, вы бы лучше табличку с тестовыми данными подготовили. А то ведь не только вам одному это делать лень.
9 авг 11, 01:16    [11088899]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
aleks2
Guest
kDnZP
klivzez, вы бы лучше табличку с тестовыми данными подготовили. А то ведь не только вам одному это делать лень.


1. Не. Тредстартеру лучше помедитировать на тему: нафега козе баян, а мине этот геморрой?
2. Ибо он даже вменяемо поставить задачу не могет. И про full outer join не читал.

;with
   curr as (select *, ROW_NUMBER() OVER(PARTITION Organisation ORDER BY ID) N from table WHERE Organisation=@organisation AND DateOfCorrection=@dateofcorrection)
  ,prev as (select *, ROW_NUMBER() OVER(PARTITION Organisation ORDER BY ID) N  from table WHERE Organisation=@organisation AND DateOfCorrection=(select max(DateOfCorrection) from table as q where q.DateOfCorrection<@dateofcorrection))
select t.value, o.value oldValue
from curr FULL JOIN prev
on 
curr.Organisation=prev.Organisation AND curr.n=prev.n
9 авг 11, 07:28    [11089076]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
klivzez
Member

Откуда:
Сообщений: 12
Спасибо, так работает, только появился вопрос.
Вот то что получилось нужно объединить в юнион с другим запросом, и все это в СТЕ.
Подскажите синтаксис для

with
СТЕ_main as
(
===============
работающий запрос
===============
UNION ALL
===============
Ваш запрос
===============
)

select *,(еще кое что) from CTE_main

Естественно "Ваш запрос" я преобразовал так что на выходе получаю точно такие же (такое же количество) столбцов что и в первом запросе.

Собственно вопрос в том именно как писать после юниона, потому что он на точку с запятой ругается
9 авг 11, 11:49    [11090176]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
klivzez,

Оператор перед WITH обязательно должен заканчиваться точкой с запятой
9 авг 11, 11:53    [11090209]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
klivzez
Member

Откуда:
Сообщений: 12
Обошелся без ЦТЕшки... всем спасибо
9 авг 11, 12:24    [11090491]     Ответить | Цитировать Сообщить модератору
 Re: JOIN самой себя, проблема.  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
klivzez,

SELECT 'Test' tst

;with
СТЕ_main as
(
	--===============
	--работающий запрос
	--===============
	SELECT 1 a, 2 b, 3 c
	UNION ALL
	--===============
	--Ваш запрос
	--===============
	SELECT 3, 4, 5
)
select *,7 d,8 e, 9 f from СТЕ_main

-- или

;with
СТЕ_main as
(
	--===============
	--работающий запрос
	--===============
	SELECT 1 a, 2 b, 3 c
), cte2 AS (
	SELECT * FROM СТЕ_main
	UNION ALL
	--===============
	--Ваш запрос
	--===============
	SELECT 3, 4, 5
)
select *,7 d,8 e, 9 f from cte2

-- А вообще, подробнее о синтаксисе в BOL
9 авг 11, 12:28    [11090527]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить