Reputation: 45
I am trying to run sth like following, but it keeps on giving me null 'Value2' in case ID_period is not 10. I've tried WITH
clause, but the script is too complex to provide multiple selects from that.
Example:
SELECT Y.ID_period, Y.ID_country, Y.Value,
(select Y.Value where ID_period = 10 and ID_country = Y.ID_country) as Value2
FROM (select A.ID_period, A.ID_country, A.Value
from dbo.xyz as A) Y
Thanks for any idea :)
Upvotes: 0
Views: 147
Reputation: 239714
Here's one that avoids the full re-query on the assumption that the "Period" extracting subquery (A
) will be cheaper than the full re-query. If it's not, it's unlikely to be much of an improvement:
declare @t table (Period_ID int, Country varchar(10),Value int)
insert into @t(Period_ID,Country,Value) values
(0,'UK',0),(10,'UK',10),(20,'UK',20),(30,'UK',30)
select
*
from (
select
COALESCE(A.Period_ID,Y.Period_ID) as Period_ID,
Y.Country,
Y.Value,
Z.Col
from
(select * from @t) Y
cross apply
(select CASE WHEN y.Period_ID = 10 THEN 'Value2' ELSE 'Value1' END as Col) Z
outer apply
(select Period_ID from @t t where t.Country = Y.Country
and Y.Period_ID = 10 and t.Period_ID != 10) A
) B
pivot (MAX(Value) for Col in (Value1,Value2)) C
Result:
Period_ID Country Value1 Value2
----------- ---------- ----------- -----------
0 UK 0 10
20 UK 20 10
30 UK 30 10
Note that I'm excluding a row being produced for Period_ID
10 since we've still not established via the comments whether that row is desirable (and if it is, it's definitely more work to do)
(If you take out the t.Period_ID != 10
filter in A
, you'll get a row back for Period_ID
10, but it has NULL
for Value
. I guess we could fix that with a further COALESCE
).
Upvotes: 1
Reputation: 31993
self left join can help you
if you have any special condition then you can use sub-query
SELECT Y.ID_period, Y.ID_country, Y.Value, X.value as value2
FROM
(
select A.ID_period, A.ID_country, A.Value
from dbo.xyz as A // where condition
) Y
left join
(
select A.ID_period, A.ID_country, A.Value
from dbo.xyz // where condition
) as x
on x.ID_country = Y.ID_country and x.ID_period=10
if no condition then simple self join can work for you what already said @Tim in his answer
Upvotes: 0
Reputation: 521513
I would rephrase this as a self join:
SELECT
t1.ID_period,
t1.ID_country,
t1.Value,
COALESCE(t2.Value, 'NA') AS Value2
FROM dbo.xyz t1
LEFT JOIN dbo.xyz t2
ON t1.ID_country = t2.ID_country AND t2.ID_period = 10;
Upvotes: 3