Hi All, apologies in advance. I understand basic SQL and am learning. Part of my learning philosophy is the do things right and elegantly. Not so my code (yet).
The challenge - dumbing this down, I am working on a single simply table of constituents of the ASX (Australian Stock Exchange) indices (such as the asx200 (xjo) and asx300 (xko). These are recorded at specific times when an index is updated. Mostly 1st of each month but historically this could happen anytime.
I am trying to measure the impact of a share entering into the asx200 (~top 200 by market cap). I am assuming it is already in the asx300 (~top 300 by market cap).
What I am trying to achieve is to get the market cap off the first 12 months (up to) AND the market cap prior to the asx200 entry. The latter is giving me grief.
To give you some real data:
select * from asx200_entries
where issue='APX'
issue | entry_date |
---|---|
APX | 2018-07-01 00:00:00.000 |
So APX entered the ASX200/XJO on 1st of June.
The table holding all data has a form of:
select * from index_constituents
where issue = 'APX'
and market_index in ('XJO','XKO')
market_index | record_date | exchange | issue | sector | market_cap | weight |
---|---|---|---|---|---|---|
XJO | 2018-07-01 00:00:00.000 | ASX | APX | Information Technology | 1422230000.00 | 0.08 |
XJO | 2018-08-01 00:00:00.000 | ASX | APX | Information Technology | 1156040000.00 | 0.06 |
XJO | 2018-09-01 00:00:00.000 | ASX | APX | Information Technology | 1631870000.00 | 0.09 |
XJO | 2018-10-01 00:00:00.000 | ASX | APX | Information Technology | 1487100000.00 | 0.08 |
XKO | 2017-10-01 00:00:00.000 | ASX | APX | Information Technology | 509340000.00 | 0.03 |
XKO | 2017-11-01 00:00:00.000 | ASX | APX | Information Technology | 543556000.00 | 0.03 |
XKO | 2017-12-01 00:00:00.000 | ASX | APX | Information Technology | 698604000.00 | 0.04 |
XKO | 2018-01-01 00:00:00.000 | ASX | APX | Information Technology | 872067000.00 | 0.05 |
XKO | 2018-02-01 00:00:00.000 | ASX | APX | Information Technology | 967057000.00 | 0.05 |
XKO | 2018-03-01 00:00:00.000 | ASX | APX | Information Technology | 1099310000.00 | 0.06 |
XKO | 2018-04-01 00:00:00.000 | ASX | APX | Information Technology | 945229000.00 | 0.05 |
XKO | 2018-05-01 00:00:00.000 | ASX | APX | Information Technology | 1024970000.00 | 0.06 |
XKO | 2018-06-01 00:00:00.000 | ASX | APX | Information Technology | 1085580000.00 | 0.06 |
XKO | 2018-07-01 00:00:00.000 | ASX | APX | Information Technology | 1422230000.00 | 0.08 |
XKO | 2018-08-01 00:00:00.000 | ASX | APX | Information Technology | 1156040000.00 | 0.06 |
XKO | 2018-09-01 00:00:00.000 | ASX | APX | Information Technology | 1631870000.00 | 0.09 |
XKO | 2018-10-01 00:00:00.000 | ASX | APX | Information Technology | 1487100000.00 | 0.08 |
The query that extracts up to 12 months (eventually):
select xjo.issue, xko.record_date, xko.market_cap
from asx200_entries xjo
left join index_constituents xko
on xjo.issue=xko.issue
where
xko.record_date >= xjo.entry_date
and xko.market_index='XKO'
and xjo.issue='APX' -- Dev
issue | record_date | market_cap |
---|---|---|
APX | 2018-07-01 00:00:00.000 | 1422230000.00 |
APX | 2018-08-01 00:00:00.000 | 1156040000.00 |
APX | 2018-09-01 00:00:00.000 | 1631870000.00 |
APX | 2018-10-01 00:00:00.000 | 1487100000.00 |
Perfect.
The query that gets the record details of the record_date prior to the entry (from asx300) is:
select top (1) xjo.issue, xko.record_date, xko.market_cap
from asx200_entries xjo
left join index_constituents xko
on xjo.issue=xko.issue
where
xko.record_date < xjo.entry_date
and xko.market_index='XKO'
and xjo.issue='APX' -- Dev
order by xko.record_date DESC
issue | record_date | market_cap |
---|---|---|
APX | 2018-06-01 00:00:00.000 | 1085580000.00 |
Perfect - the month before the asx200 list.
HOWEVER - when I union these the [order by] is applied to the union result and not the second query. Tried bracketing these and all sorts of tricks (like swapping the upper and lower parts of the union.
I know I can hack something to make this happen but would like to do this right and elegantly.
I would really welcome any/all suggestions.
Thanking you in advance.
PS the total query is:
select xjo.issue, xko.record_date, xko.market_cap
from asx200_entries xjo
left join index_constituents xko
on xjo.issue=xko.issue
where
xko.record_date >= xjo.entry_date
and xko.market_index='XKO'
and xjo.issue='APX' -- Dev
UNION
select top (1) xjo.issue, xko.record_date, xko.market_cap
from asx200_entries xjo
left join index_constituents xko
on xjo.issue=xko.issue
where
xko.record_date < xjo.entry_date
and xko.market_index='XKO'
and xjo.issue='APX' -- Dev
order by xko.record_date DESC
--order by xjo.issue, xko.record_date