I need to query an SQL database to find all distinct values of one column and I need an arbitrary value from another two columns. For example, consider the following table with three columns: CurrencyCode, BuyRate and SellRate:
CurrencyCode BuyRate SellRate
AUD 1.037 1.97
AUD 1.079 1.99
EUR 0.7288 0.8763
EUR 0.731 0.88
GBP 0.59 0.72
I wish to retrieve one row with distinct CurrencyCode, perhaps getting these three rows:
CurrencyCode BuyRate SellRate
AUD 1.037 1.97
EUR 0.7288 0.8763
GBP 0.59 0.72
I tried my SQL query like:
SELECT distinct CurrencyCode, BuyRate, SellRate FROM Currencies
But I am not getting the desired result as it districts all the columns.
Try with GROUP BY clause and MIN function as below
SELECT CurrencyCode, MIN(BuyRate), MIN(SellRate)
FROM Currencies
GROUP BY CurrencyCode
Till now I found this is the best answer to get Min(SellRate) on the basis of Min(BuyRate)
eg.
CurrencyCode BuyRate SellRate
AUD 1.037 1.97
AUD 1.079 1.89 //Changed from 1.99 to 1.89
AUD 1.038 1.77 //New row added
EUR 0.7288 0.8763
EUR 0.731 0.88
GBP 0.59 0.72
Here I am expecting AUDrows for BuyRate and SaleRate will be 1.037 and 1.97
select CurrencyCode, Min(BuyRate) as BuyRate,
(select top 1 SellRate from Currencies as C
where C.CurrencyCode=Currencies.CurrencyCode
and
C.BuyRate= Min(Currencies.BuyRate) order by SellRate) as SellRate
from Currencies
group
by CurrencyCode
Related
This question already has an answer here:
SQL combining GROUP BY and SUM
(1 answer)
Closed last year.
Is it possible to take the sum of all values where another field is the same ?
I have a table which looks like this :
id
symbol
rate
0
USD
0.98
1
USD
1.93
2
EUR
2.08
3
EUR
0.42
4
USD
0.18
So when I like to only get the list of symbols I do this:
select DISTINCT symbol from myTable
Which returns me
id
EUR
USD
What would I need to do to get a sum of all the rates ?
id
rates
EUR
2,5
USD
3,09
Thanks
Use an aggregation query:
SELECT symbol, SUM(rate) AS rates
FROM myTable
GROUP BY symbol;
I am trying to create a query that joins 3 tables with multiple prices and locations. Ex of the data I'm pulling.
Table A - product, product name
Table B - transactionid, date, product, returnreason, quantity, costprice, costamount,
location, journalid
Table C - price1, price2, price3, price4, price5, price6, product, activedate
Table C is updating prices for our products and can be the same from one date to another, or completely change depending on the market. Location in Table B can be up to four different locations.
Ex. Table C (each product is setup basically the same in the tables.)
product price1 price2 price3 price4 price 5 price6 activedate
A 0.00 0.00 0.00 0.00 0.00 0.00 1/1/11
A 0.00 0.00 0.00 0.00 0.00 0.00 2/1/11
A 1.00 0.00 0.63 0.00 1.20 0.20 1/1/12
A 1.20 0.53 0.01 1.00 0.42 0.00 4/1/13
Table B
product transactionid tdate returnreason quantity costprice costamount location journalid
A 00001 5/1/11 def 100 2.00 2.50 100 000010
B 00205 6/13/11 col 250 10.00 15.00 300 000320
A 00207 4/11/13 col 50 5.00 1.50 100 000720
I need to get the information out by the most current price for the item by date. So if I need a yearly report, I can see that for product A - price1 for 1/1/13-4/30/13 was 1.00 and for 5/1/13-present the price is now 1.20.
I have tried many things including sub queries and the latest (which is closest) to limit it by creating a where statement to be activedate<=tdate which will bring me every active date below and equal to the tdate. For this please assume product A is at location 100. How can I limit to the product active during the time frame it would be active?
Most recent...
I added line number in to make sure I got each line of the journal in...just visual.
select distinct(b.transactionid), b.tdate, b.linenum b.product, b.location,
b.journalid, c.price1, c.price2, c.price3, c.price4, c.price5, c.activedate
from Table b inner join
Table c on c.product=b.product
where c.activedate <= b.tdate
When I run this I get all dates that were less than the transaction date, but I need specific. For example the first transaction in my example, it happened on 5/1/11, when I run the query it will give me the results from table c for 1/1/11 and 2/1/11. I just need the date of the price for when the transaction took place.
I'm currently working on a project that involves using a user-provided charge table to calculate fees.
The table looks like:
MaxAmount Fee
10.00 1.95
20.00 2.95
30.00 3.95
50.00 4.95
As seen in the table above, any MaxAmount up to 10.00 is charged a 1.95 fee. Any MaxAmount between 10.01 and 20.00 is charge a 2.95 fee, etc. Finally, any MaxAmount above 50.00 is charged 4.95.
I'm trying to come up with a sql query that will return the correct fee for a given MaxAmount. However, I'm having trouble doing so. I've tried something similar to the following (assuming a provided MaxAmt of 23.00):
SELECT Fee FROM ChargeTable WHERE 23.00 BETWEEN MaxAmt AND MaxAmt
Of course, this doesn't give me the desired result of 3.95.
I'm having trouble adapting SQL's set-based logic to this type of problem.
Any and all help is greatly appreciated!
If the MaxAmount behaves as the table suggests, then you can use:
select top 1 fee
from ChargeTable ct
where #Price <= MaxAount
order by MaxAmount desc
As you describe it, you really want another row:
MaxAmount Fee
0.00 1.95
10.00 1.95
20.00 2.95
30.00 3.95
50.00 4.95
Your original table does not have enough values. When you have 4 break points, you actually need 5 values -- to handle the two extremes.
With this structure, then you can do:
select top 1 fee
from ChargeTable ct
where #Price >= MaxAount
order by MaxAmount desc
You could try something like:
SELECT min(Fee) FROM Fees WHERE 23<=MaxAmount
Have a look here for an example:
http://sqlfiddle.com/#!2/43f2a/5
Imagine we have 2 Tables, A and B, having the same structure, as follows:
Currency, Spot, Exposure, Fixing.
We want to join these two tables in order to have a query on, for example, Fixing = '2013-01-03' and having the major list of currencies (there is not always correspondence between currencies in A and currencies in B).
1 condition: A.Fixing = B.Fixing
2 condition: A.Currency = B.Currency (returning also Currency values not matched)
This is an example: We have the USD currency in table A for that day requested but we don't have it on table B. What we want for that day is a join table having one row with USD followed by the Exposure value in Table A and followed by zero (because ARS was not in table B and therefore it has no Exposure on USD)
How can we write a query?
Below Tables and results:
Table A:
Currency Spot Exposure Fixing
-------- ------- ------------ ----------
AUD 1.3023 -504,561.00 30/01/2013
CHF 1.2378 268,243.00 30/01/2013
GBP 0.8597 2,204.00 30/01/2013
JPY 123.635 -552.00 30/01/2013
USD 1.3572 5,242.00 30/01/2013
AUD 1.300 -574,561.00 29/01/2013
CHF 1.235 545,152.00 29/01/2013
GBP 0.858 1,155,212.00 29/01/2013
JPY 123.388 -45,115.00 29/01/2013
USD 1.354 22,468.00 29/01/2013
Table B:
Currency Spot Exposure Fixing
-------- ------- ------------- ----------
AUD 1.3023 256,442.00 30/01/2013
CHF 1.2378 -4,456,421.00 30/01/2013
GBP 0.8597 15,246.00 30/01/2013
JPY 123.635 1,243,146.00 30/01/2013
AUD 1.300 41,246.00 29/01/2013
CHF 1.235 243.00 29/01/2013
GBP 0.858 54,564.00 29/01/2013
JPY 123.388 140.00 29/01/2013
Results:
Currency A.Exposure B.Exposure Fixing
-------- ----------- ------------- ----------
AUD -504,561.00 256,442.00 30/01/2013
CHF 268,243.00 -4,456,421.00 30/01/2013
GBP 2,204.00 15,246.00 30/01/2013
JPY -552.00 1,243,146.00 30/01/2013
USD 5,242.00 - 30/01/2013
EDITED: The left outer join allows you to grab everything in table a and matching values in table b and having NULLs where there isn't data in table b. Use the ISNULL() function to give you cleaner results by checking for NULL values and if it finds one, replacing it with a different value of your choosing.
select
a.Currency
, a.Spot
, a.Exposure as a_Exposure
, ISNULL(b.Exposure, 0) as b_Exposure
, a.Fixing
from a
left outer join b
on b.Currency = a.Currency
and b.Fixing = a.Fixing
where a.Fixing = '2013-01-30';
I have changed the query to reflect the suggestion from Clockwork-Muse. You will need to add any columns you want data returned for.
I hv two tables:-
First Table:-
EFF_DATE RATE CURRENCY TYPE
20110101 1.286 USD 1
20110101 1.300 USD 2
20110201 1.275 USD 1
20110201 1.290 USD 2
20110301 1.275 USD 1
20110301 1.285 USD 2
20110401 1.260 USD 1
20110401 1.270 USD 2
20110501 1.225 USD 1
20110501 1.230 USD 2
2nd Table:-
PO_NO TRANS_DATE ACCT_DATE SUPP_NO CURRENCY LOCAL_AMT
1000068 20110114 20110115 S016 USD 16,500.00
1000070 20110214 20110215 S016 USD 7,660.00
1000072 20110317 20110322 S025 USD 1,080.00
1000132 20110314 20110315 S037 USD 3,500.00
1000133 20110414 20110415 S038 USD 14,500.00
Based on ACCT_DATE & TYPE = 1, I wish to add a RATE column & the result should look like this:-
PO_NO TRANS_DATE ACCT_DATE SUPP_NO CURRENCY LOCAL_AMT RATE
1000068 20110114 20110115 S016 USD 16,500.00 1.286
1000070 20110214 20110215 S016 USD 7,660.00 1.275
1000072 20110317 20110322 S025 USD 1,080.00 1.275
1000132 20110314 20110315 S037 USD 3,500.00 1.275
1000133 20110414 20110415 S038 USD 14,500.00 1.26
1000170 20110531 20110531 S016 USD 15,400.00 1.225
I used the below SQL to run but for some reasons, it just keep looping without any output:-
SELECT st.*, ft.rate
FROM second_table st
LEFT JOIN first_table ft
ON (MONTH(acct_date) = MONTH(eff_date) AND YEAR(acct_date) = YEAR(eff_date) )
where ft.TYPE=1
Pls help.
Thanks.
Not very large. If I remove ft.TYPE=1,
it will generate the result almost
immediately.
Based on your comment above you need to put an index on ft.TYPE
You could also set up the query like this which might improve how the optimizer runs the query
SELECT st.*, ft.rate
FROM second_table st
LEFT JOIN first_table ft
ON ft.TYPE=1 AND MONTH(acct_date) = MONTH(eff_date) AND YEAR(acct_date) = YEAR(eff_date)
Also, are the dates stored as strings or as datetime values. If they are stored as strings you should do a string compare instead of coverting to datetimes and then extracting the month and year.
How large are your tables? Your joining on an agrigate function so it will be very slow if the tables are large