Find most recent price in price list - sql

I have a table with Item, Price and Price Date columns. What I need to do is filter out only the old prices, showing only the most recent price for each item. I am using MS Access 2007 and need to reference the most updated price in some VBA I am writing, and in my research I cannot find a way to programmaticly access pivot table data for customer pricing elsewhere in the DB.
Example:
Table
Item | Price | Price Date

You can use a correlated subquery:
select t.*
from t
where t.pricedate = (select max(t2.pricedate)
from t as t2
where t2.item = t.item
);

One option uses a subquery to find the most recent price for each item:
SELECT t1.Item, t1.Price, t1.PriceDate
FROM yourTable t1
WHERE t1.PriceDate = (SELECT MAX(t2.PriceDate) FROM yourTable t2 WHERE t2.Item = t1.Item);

This is a bit more efficient than using MAX()-function:
SELECT Item, Price, PriceDate
FROM customer_pricing t1
WHERE NOT EXITS(
SELECT *
FROM customer_pricing t2
WHERE t1.item = t2.item
AND t1.PriceDate < t2.PriceDate
)

The solution was by #dewey and was
SELECT t1.item, t1.unit_price1, t1.effect_date, t1.site_ref
FROM dbo_itemprice_mst_all AS t1
WHERE (((t1.site_ref)="MED" Or (t1.site_ref)="CRD") AND ((Exists (SELECT *
FROM dbo_itemprice_mst_all t2
WHERE t1.item = t2.item
AND t1.effect_date < t2.effect_date
))=False))
ORDER BY t1.item;

Related

Join Tables Where Absolute of Occurrences Equal to Absolute of Single Occurrence

Problem: I am currently trying to join two tables in Access where the absolute value of the total of multiple occurrences of one field in one table is equal to the absolute value of the occurrence in another table.
Am I able to use the Abs function in the WHERE statement? Everything I saw involved the function being used in the SELECT statement. Do I need to create separate queries to get the absolute values? It would also work if I were to check to see if they balance out rather than getting the absolute value.
In one table, a certain value will repeat multiple times while it will only appear once in the other table. How can I get the absolute values of the totals in order to compare it to the single occurrence in the other table? Thanks!
Table 1
Reference
Amount
55555
$15
55555
$20
Table 2
Reference
Amount
55555
-$35
If these are equal or if they balance out, they should appear on a query. If these aren't equal but the reference number and a partial amount appears, they should appear on another query.
The matching query is relatively simple. Just aggregate and compare the values:
select t2.reference, t2.amount
from (select reference, sum(amount) as amount
from table2
group by reference
) as t2 inner join
(select reference, sum(amount) as amount
from table1
group by reference
) as t1
on t1.reference = t2.reference
where t2.amount + t1.amount = 0;
However, the non-matches are much trickier -- because presumably a reference could be missing from either table. And MS Access does not support full join. One method is:
select t2.reference, t2.amount, t1.amount
from (select reference, sum(amount) as amount
from table2
group by reference
) as t2 left join
(select reference, sum(amount) as amount
from table1
group by reference
) as t1
on t1.reference = t2.reference
where t2.amount + t1.amount <> 0 or t1.amount is null
union all
select t1.reference, null, sum(amount)
from table1 as t1
where not exists (select 1 from table2 as t2 where t2.reference = t1.reference)
group by t1.reference;
Aggregate data in Table1 and join to Table2.
Consider:
SELECT Table2.*, SumAmt FROM Table2
INNER JOIN (SELECT Reference, Sum(Amount) AS SumAmt FROM Table1 GROUP BY Reference) AS T
ON Table2.Reference = T.Reference
WHERE SumAmt = -Table2.Amount;
You can list if the amounts match or not, no Abs is needed:
Select
Table2.Reference,
Table2.Amount,
(T.Total = -Table2.Amount) As T1Match
From
Table2
Inner Join
(Select
Table1.Reference,
Sum(Table1.Amount) As Total
From
Table1
Group By
Table1.Reference) As T
On T.Reference On Table2.Reference
you can use sub-query as follows:
select t1.reference from
(select reference, sum(amount) as amount from table1 group by reference) t1
join table2 t2
on abs(t1.amount) = abs(t2.amount)

How to get latest date that is not greater then record date?

I have table with names with eomonth history.
I need to join another table that has information about "tests" performed on names:
The result table should show the latest ID and date of performed test but the date of test cannot be greater than the data month:
Any ideas how to perform this?
I am guessing that you want the most recent EOMONTH from the second table for each row in the first table. If that is the correct interpretation, then you can simply use apply:
select t1.*, t2.*
from table1 t1 outer apply
(select top (1) t2.*
from table2 t2
where t2.test_id = t1.test_id and t2.eomonth <= t1.test_date
order by t2.eomonth desc
) t2;
This join works perfectly:
from table1 a
left join table2 b on a.name = b.name and a.eomonth >= b.id_date and a.eomonth < LAG(b.id_date,1,'3000-01-01') OVER (PARTITION BY name ORDER BY b.id_date desc)

SQL Server query showing most recent distinct data

I am trying to build a SQL query to recover only the most young record of a table (it has a Timestamp column already) where the item by which I want to filter appears several times, as shown in my table example:
.
Basically, I have a table1 with Id, Millis, fkName and Price, and a table2 with Id and Name.
In table1, items can appear several times with the same fkName.
What I need to achieve is building up a single query where I can list the last record for every fkName, so that I can get the most actual price for every item.
What I have tried so far is a query with
SELECT DISTINCT [table1].[Millis], [table2].[Name], [table1].[Price]
FROM [table1]
JOIN [table2] ON [table2].[Id] = [table1].[fkName]
ORDER BY [table2].[Name]
But I don't get the correct listing.
Any advice on this? Thanks in advance,
A simple and portable approach to this greatest-n-per-group problem is to filter with a subquery:
select t1.millis, t2.name, t1.price
from table1 t1
inner join table2 t2 on t2.id = t1.fkName
where t1.millis = (select max(t11.millis) from table1 t11 where t11.fkName = t1.fkName)
order by t1.millis desc
using Common Table Expression:
;with [LastPrice] as (
select [Millis], [Price], ROW_NUMBER() over (Partition by [fkName] order by [Millis] desc) rn
from [table1]
)
SELECT DISTINCT [LastPrice].[Millis],[table2].[Name],[LastPrice].[Price]
FROM [LastPrice]
JOIN [table2] ON [table2].[Id] = [LastPrice].[fkName]
WHERE [LastPrice].rn = 1
ORDER BY [table2].[Name]

want to select same product_id but bigger id row

i have some problem about sql , i want to select the bigger warehouse_product_id and with same product_id row,i have try to use
please help
Table:
http://postimg.org/image/mkavxnmg9/
i want to:
http://postimg.org/image/8msomu47l/
SELECT warehouse_product_id FROM [your table] where product_id="value"
unless I missed what you're getting at, which is entirely possible
You seem to be looking for a greatest-n-per-group solution. For a given product_id and warehouse_id pair you need to get the max warehouse_product_id:
SELECT t1.* FROM aTable t1
JOIN (
SELECT product_id, warehouse_id, MAX(warehouse_product_id) maxVal
FROM aTable
GROUP BY product_id, warehouse_id
) t2
ON t1.product_id = t2.product_id AND t1.warehouse_id = t2.warehouse_id AND t1.warehouse_product_id = t2.maxVal
Alternatively:
SELECT t1.* FROM aTable t1
LEFT JOIN aTable t2
ON t1.product_id = t2.product_id AND t1.warehouse_id = t2.warehouse_id AND t1.warehouse_product_id < t2.warehouse_product_id
WHERE t2.warehouse_product_id IS NULL
These solutions should work on most DBMS.
I have assumed qty and enable have the same values for the same warehouse/product. If not, you'll need to join back to the table to get those.
select warehouse_id, max(warehouse_product_id) as item_id, product_id, max(qty), max(enable)
from warehouse_product
group by warehouse_id, product_id

SQL querying for set of distinctive values

I have a DB table with columns ID, time, and text. ID is non-unique. I'm trying to construct a query that says "For each distinct IDs, give me the row whose time is the greatest value before T". The second part is easy enough with a ORDER BY DESC LIMIT 1 WHERE time < T, but I don't know how to ensure I get coverage of all the IDs.
As an example:
ID,time,text
1,10,"hello"
1,20,"world"
2,10,"foo"
3,10,"bar"
4,50,"blah"
If I searched with time 25, I'd want:
1,20,"world"
2,10,"foo"
3,10,"bar"
I could do this is multiple queries by searching for DISTINCT IDs and then doing a search for each, but I was hoping there was a more efficient compound query form.
SELECT t.ID, t.time, t.text
FROM YourTable t
INNER JOIN (SELECT ID, MAX(time) AS MaxTime
FROM YourTable
WHERE time < T
GROUP BY ID) q
ON t.ID = q.ID
AND t.time = q.MaxTime
You can use a sub-query:
select t1.id, t1.time, t1.test
from yourtable t1
inner join
(
select id, max(time) MaxTime
from yourtable
where time < T
group by id
) t2
on t1.id = t2.id
and t1.time = t2.time