finding highest total price and converting - sql

So I have to use a query where I list the trade id stock id and the total price converted to us dollars where it is the highest price total.
SELECT
tr.trade_id, tr.stock_id, round(tr.price_total * con.exchange_rate,2)
as "US Dollars"
from trade tr
JOIN stock_exchange se
on se.STOCK_EX_ID = tr.STOCK_EX_ID
JOIN currency curr
on curr.CURRENCY_ID = se.currency_id
JOIN conversion con
on con.from_CURRENCY_ID = curr.CURRENCY_ID
WHERE (tr.PRICE_TOTAL) = (Select Max(price_total) from trade) and curr.name =
'Dollar' and tr.stock_ex_id is not NULL
group by tr.trade_id, tr.stock_id, round(tr.price_total), tr.price_total,
round(tr.price_total * con.exchange_rate,2);
Trade (trade_id PK, stock_id FK2, transaction_time, shares, stock_ex_id FK1,price_total)
Stock-exchange( stock_ex_id PK, name, symbol, currency_id FK1)
conversion( from_currency_id PK, to_currency_id)
currency ( currency_id PK, name, symbol
expected output should be -
trade_id - 1 stock_id 1, price (non conversion) (225000000)
I'm not sure why in my output i get nothing. Any suggestions to fix this? Sorry if i did not format the question right

But you could start by seeing what your select max query returns, and then filtering down the trade table by that value. Trace this though all of your tables to see where the data on your trade table isn't on the others.
OR put you curr.name criteria up with the join and specify a LEFT JOIN for the last two tables to see if the data is missing like below:
SELECT tr.trade_id
,tr.stock_id
,round(tr.price_total * con.exchange_rate, 2) AS "US Dollars"
FROM trade tr
LEFT JOIN stock_exchange se
ON se.STOCK_EX_ID = tr.STOCK_EX_ID
LEFT JOIN currency curr
ON curr.CURRENCY_ID = se.currency_id
AND curr.name = 'Dollar'
LEFT JOIN conversion con
ON con.from_CURRENCY_ID = curr.CURRENCY_ID
WHERE (tr.PRICE_TOTAL) = (SELECT Max(trm.price_total) FROM trade trm)
AND tr.stock_ex_id IS NOT NULL

It could be other things as well, but one spot to look is this
You say WHERE tr.PRICE_TOTAL = (Select Max(price_total) from trade)
AND curr.name = 'Dollar'
If the trade with the Maximum price_total is not in Dollars, then you'll get nothing.
You need to either change your "Select Max(price_total) from trade" to get maximum values for Dollar trades only, or else get all the valid trades in a subquery and then get the maximum value from that.
After comment below - to debug - run "Select * from trade where price_total = (Select Max(price_total) from trade)" to get the valid trade record(s). Then look at them - they are going to fail somewhere - no STOCK_EX_ID on trade, or one of the other joins fails - you need to start from known data and go from there.

Related

How to add specific if condition in sql

I have built this query (snapshot attached) to check if there is any staleness in prices by comparing today's price with previous day price for certain timezones, what i need is it should only throw only that object_id which shows '0' as BP_move for the mentioned timezones. for eg in the snapshot we can see that AED fx price is 0 for across all the timezones so it is acceptable but other ccy like EUR, GHS ,KES ,NZD and QAR are stale only for one or two timezones so those should not get published in output. is there any if condition i can use in this query ?
select distinct
vyc.asof, vyc.timezone, vyc.object_id, i.name,
vpf.rate * 100 todays_rate, vpf2.rate * 100 prior_rate,
(vpf.rate - vpf2.rate) * 1000 bp_move
from
val_yield_curves vyc
inner join
val_prices_fx vpf on vyc.asof = vpf.asof
and vyc.rowkey = vpf.curve
inner join
val_yield_curves vyc2 on vyc.timezone = vyc2.timezone
and vyc2.asof = case when to_char(sysdate,'DY') = 'MON' then trunc(sysdate-3) else trunc(sysdate-1) end
and vyc.object_id = vyc2.object_id
inner join
val_prices_fx vpf2 on vyc2.asof = vpf2.asof
and vyc2.rowkey = vpf2.curve
and vpf.instrument = vpf2.instrument
inner join
instruments i on i.pkey = vpf.instrument
where
vyc.object_id like '%Spot%'
and vyc.timezone in ('L0200', 'L1000', 'L1200', 'L1500')
and (vpf.rate - vpf2.rate) * 1000 in '0'
and vyc.asof = trunc(sysdate)
order by
vyc.object_id
I don't know if I understood correctly your problem but...
If you don't need timezone information, you can
GROUP BY object_id, name, rates
HAVING COUNT(DISTINCT Timezone) >= 4
If you need timezone information, you can add a "OBJECT_ID IN (SELECT...)" condition in your WHERE. You have to make it check if you have the right number of lines for your OBJECT_ID. You can GROUP BY/HAVING COUNT this subrequest as above and returns OBJECT_ID.

Get Percentage From The Sum Of Multiple Queries

I am trying to get a percentage from the total gross divided by the concessions (credits and discounts). The first query gives me all the gross income, the next two queries give me the concessions. These two queries are almost the same with the exception of the criterias. I can't figure out how to get the percentage. I need to show the Gross Potential Rate, Effective Rate After Concessions and Percentage of Difference which is about 2%. Your assistance is greatly appreciated.
'Gross Potential Rate' AS Status,
sum(Units.dcPushRate) as DollarAmt
from Units
inner join UnitTypes with (nolock) on UnitTypes.UnitTypeID = Units.UnitTypeID
where Units.SiteID = '30250' AND Units.dDeleted IS NULL AND sUnitName <> 'POS$' and units.sUnitName LIKE 'H%'
UNION ALL
Select 'Effective Rate After Concessions' as Status, SUM(c) FROM
(
select sum(charges.dcPrice) * -1 as c from Charges
inner join ledgers with (nolock) on charges.ledgerid = ledgers.ledgerid
inner join units with (nolock) on units.unitid = ledgers.unitid
where charges.siteid ='30250' and units.sUnitName LIKE 'H%' and charges.dchgstrt BETWEEN #dStart AND #dEnd and charges.dcstdprice = charges.dcPrice and charges.concessionid IS NOT NULL
UNION ALL
select sum(charges.dcPrice) * -1 as c from Charges
inner join ledgers with (nolock) on charges.ledgerid = ledgers.ledgerid
inner join units with (nolock) on units.unitid = ledgers.unitid
where charges.siteid ='30250' and units.sUnitName LIKE 'H%' and charges.dchgstrt BETWEEN #dStart AND #dEnd and charges.dcstdprice ='0.00'
UNION ALL
select
sum(Units.dcPushRate) as DollarAmt
from Units
inner join UnitTypes with (nolock) on UnitTypes.UnitTypeID = Units.UnitTypeID
where Units.SiteID = '30250' AND Units.dDeleted IS NULL AND sUnitName <> 'POS$' and units.sUnitName LIKE 'H%'
) a
Don't try to solve everything in SQL. You will have to use the same queries again in a calculation to work out the percentage values.
You might be better off leaving the percentage calculation to your presentation layer as it will have the necessary values in a simpler form.

Select only rows mith minimum cost

I need to pull back a set of data for a view where only rows with the the minimum cost are returned. I am joining 3 tables and they are big tables (225 million records a piece give or take) so performance is essential.
SELECT RIC.CarrierName, L.LoadGuid, RIC.RateIQCarrierid, RIRD.Cost
FROM tblLoads L
INNER JOIN RateIQRecord RIR ON L.LoadGuid = RIR.LoadGuId
INNER JOIN RateIQCarrier RIC ON RIR.RateIQRecordID = RIC.RateIQRecordID
INNER JOIN RateIQRateDetail RIRD ON RIC.RateIQRecordID = RIRD.RateIQRecordID
AND CAST(L.CreatedDate AS Datetime) Between '03/3/2014' and '03/3/2014 23:59:59.997'
Here is an example of the data set based of the code above
CarrierName LoadGuid Carrierid Cost
Carrier a FF98010A-90CE-4541-AB88-683645352712 210677951 192.51
Carrier a FF98010A-90CE-4541-AB88-683645352712 210677921 153.17
Carrier b FF98010A-90CE-4541-AB88-683645352712 210677925 196.28
Carrier b FF98010A-90CE-4541-AB88-683645352712 210677947 280.65
Carrier b FF98010A-90CE-4541-AB88-683645352712 210677949 241.71
Here is what I need:
CarrierName LoadGuid Carrierid Cost
Carrier a FF98010A-90CE-4541-AB88-683645352712 210677921 153.17
Carrier b FF98010A-90CE-4541-AB88-683645352712 210677925 196.28
Try this out:
Note:I'm assuming you have SQL Server 2008 or above. ROW_NUMBER() won;t work otherwise.
SELECT *
FROM
(
SELECT RIC.CarrierName,
L.LoadGuid,
RIC.RateIQCarrierid,
RIRD.Cost,
--Partition says look at each carrier as a group, then number them in order of cost lowest to highest.
ROW_NUMBER() OVER (PARTITION BY RIC.CarrierName ORDER BY Cost) rank_num
FROM tblLoads L
INNER JOIN RateIQRecord RIR
ON L.LoadGuid = RIR.LoadGuId
INNER JOIN RateIQCarrier RIC
ON RIR.RateIQRecordID = RIC.RateIQRecordID
INNER JOIN RateIQRateDetail RIRD
ON RIC.RateIQRecordID = RIRD.RateIQRecordID
--Don't do it this way
--AND CAST(L.CreatedDate AS Datetime) Between '03/3/2014' and '03/3/2014 23:59:59.997'
--Try this instead
AND CAST(L.CreatedDate AS DATE) = '03/03/2014'
) A
--Only grab the lowest number aka first of row number
WHERE A.rank_num = 1

Use last available currency rate by date available to calculate totals

I am trying to convert currency rates on orders.
The currency rates table is updated daily End of day for that particular day, however an order can be created earlier in the day, and as a result the rate will not be reflected with the current query. How would I add case statements and modify the query where by if the currency rate for the day does not exist use the last currency date available (within the table).
#Curr is the desired currency code. Could be 'USD', 'GBP' etc.
SELECT OrderNumber
,(CASE WHEN #Curr<>cur.code THEN
o.price * (SELECT Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
AND xr.Date= ISNULL((SELECT TOP 1 CAST(Crtd_DateTime AS Date) FROM ApDoc apdoc
WHERE apdoc.PONbr = o.OrderNumber AND apdoc.PONbr>''
ORDER BY apdoc.Crtd_DateTime DESC),o.orderdate)
)
ELSE o.price
END ) as o.price
from orders o
join currency c on c.curcode = o.curcode
Why not this:
...
o.price * (SELECT TOP 1 Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
ORDER BY xr.Date DESC)
...
If there are future dates in the xchangeRates table, all you have to do is add an additional filter to the WHERE clause to limit xr.Date to <= today.
EDIT: to handle this requirement:
if the invoice was created in the apdoc the it uses that Date for the
exchange rate, but if not then it uses the date the order was created.
forget your subselect to apDoc and JOIN it to orders in the outer query instead:
LEFT OUTER JOIN apDoc
ON apdoc.PONbr = o.OrderNumber
And then do this for your subquery instead of what I have above:
o.price * (SELECT TOP 1 Rate FROM xchangeRates xr
WHERE xr.FromCurrCode = c.Code
AND xr.ToCurrCode = #Curr
AND xr.Date =< COALESCE(CAST(apdoc.Crtd_DateTime AS Date),o.OrderDate)
ORDER BY xr.Date DESC)
nb: I CAST Crtd_DateTime AS Date because you did it in your code, and for all I know it's a varchar, but if it's a Datetime datatype, then the cast isn't necessary in my solution.

PostgreSQL: Outer and self join

I want to do an outer join on the same table, but I'm getting unexpected results.
This is what my "stock" table looks like:
price_timestamp, security, price_type, open, high, low, close
"2014-05-01 00:00:00-07";"SPY US EQUITY";"ASK"; 188.54;188. 57;188.54;188.57
"2014-05-01 07:59:00-07";"SPY US EQUITY";"ASK"; 188.72;188. 72;188.72;188.72
"2014-05-01 08:01:00-07";"SPY US EQUITY";"ASK"; 188.71;188. 72;188.71;188.72
"2014-05-01 13:30:00-07";"SPY US EQUITY";"TRADE"; 188.22;188. 27;188.21;188.26
"2014-05-01 13:31:00-07";"SPY US EQUITY";"TRADE"; 188.27;188. 35;188.26;188.35
...
price_type can be BID, ASK or TRADE. I want a query that returns price_timestamp, security, bid price (which would be close price where price_type = 'BID'), and trade price (which would be close price where price_type = 'TRADE).
This is what I have:
SELECT b.price_timestamp, b.security, b.close AS bid, t.close AS trade
FROM stock b
FULL OUTER JOIN stock t
ON b.price_timestamp = t.price_timestamp
AND b.security = t.security
WHERE b.price_type = 'BID'
AND t.price_type = 'TRADE'
This returns 19370 records. There are 40147 bid prices, 19399 trade prices, so I'm expecting at least max(40147, 19399) = 40147 records. At a glance, it looks it's returning an INNER JOIN.
I've also tried moving "b.security = t.security" in the ON cluse to the WHERE clause -- no luck.
You're getting fewer records because on the where clause you're referring both aliases 'b'& 't'. So, it is filtering only those joined records where b.price_type = 'BID' and t.price_type = 'TRADE'
Try moving the where conditions into the joins
For example:
SELECT b.price_timestamp, b.security, b.close AS bid, t.close AS trade
FROM stock b
FULL OUTER JOIN stock t
ON b.price_timestamp = t.price_timestamp
AND b.security = t.security
AND t.price_type = 'TRADE'
WHERE b.price_type = 'BID'
This would return all records from alias 'b' where b.price_type = 'BID', and at least one record from alias 't'. If no matching records are found from 't', a null records will be returned.