How to show 2nd, 3rd etc. highest values in a table using SQL Server 2005? - sql-server-2005

I'm looking for a way to add some more columns to a query to show values other than just the top one.
It is essentially show show quantities on purchase orders in date order with the newest first.
this is what we have so far which give is the more recent value.
(select top 1
s0.ShipDate
from
por1 s0
where
s0.itemcode=t0.itemcode
and s0.OpenQty<>0
order by
s0.shipdate)as 'Delivery Date',
(select top 1
s0.OpenQty
from
por1 s0
where
s0.itemcode=t0.itemcode
and s0.OpenQty<>0
order by
s0.shipdate asc)as 'Open Qty'
How can I add 3 more columns to show the 2nd, 3rd and 4th highest value please?

Related

SQL query for calculated column

I have a table that looks like this -
Table screenshot link - https://i.stack.imgur.com/Pztpq.png
I want to add a new column 'Manufacturer_Updated', such that -
If any particular 'Product' has more than 1 (distinct) 'Manufacturer', then the Manufacturer having highest 'Sales' should be populated in the 'Manufacturer_Updated' column for all rows of that particular 'Product'.
Ex - In the above screenshot, Product - 'TOTAL HAIR CARE NA' has 2 different Manufacturer, so in the 'Manufacturer_Updated' column, 'SEXY HAIR CONCEPTS' should appear for both the rows, as it has the higher sales.
Could someone pls help with this query? Thanks in Advance!
Something like this should work:
SELECT Manufacturer, Product, Sales, Manufacturer as Manufacturer_Updated FROM
WHERE amt_of_manufacturers > 1
((SELECT Product, max(Sales) as Sales, count(distinct Manufacturer) as amt_of_manufacturers
FROM your_table
GROUP BY Product) as q1
left join
(SELECT Manufacturer, Sales, Product
FROM your_table
) as q2
ON q1.Sales = q2.Sales
AND q1.Product = q2.Product
) as q3
In the first query (q1), you're retrieving maximum sales per each product along with amount of manufacturers for a specific product (used later in upper query). In the second one (q2) you just need to retrieve Manufacturer (to transform it later to Manufacturer_Updated), Sales and Product (as join keys). After this you only need to filter out all products with single manufacturer.
Alternatively, if you want to keep those, you can remove where amt_of_manufacturers > 1 and replace Manufacturer_Updated in the upper query with the following:
CASE WHEN
amt_of_manufacturers <=1 THEN null
ELSE Manufacturer
END AS Manufacturer_Updated

How do i Calculate Fill Order Rate Using Sales Order Line Item

We are trying to write a query to find out how much of the order was fullfilled in the first invoice on that order. Look at ArTrnInvoice table for Invoice info and OrderDetail for orders info. Compare qty ordered on each sales order line to what was fulfilled on the first invoice on that order
We tried
select case when SalesOrderLine>0 THEN QtyInvoiced /MOrderQty *100 Else End as Order_fILL_RATE FROM OrderDetail a Left JOIN
OrderHeader b ON a.SalesOrder = b.SalesOrder
WHERE b.Order Status ='9'
Basically,Trying to Output :
How much of the order was fullfilled in the first invoice - Let' say I ordered 2000$ worth of items. And Business Org invoiced this to me in two parts. First 1800$ within 10 days and then another 200$ later (or didn't ship this at all). In this case fill rate = 90%
Given Conditions
We have sql server 2012. Trying to calculate Fill Order Rate Using Order Line Item.
We have 3 table which consist of OrderHeader Info,OrderDetail Info, Invoice info table .
Structure of these tables are Here in link:
OrderDetail Table
Structure is
OrderHeader Table DDL
Also OrderStatus='9' means Fulfilled Order.
Any help on it would be much appreciated ?

Check Sequence in Max Min Values

I have a database table that Stores Maximum and Minimum Price Breaks for a Product.
Does anyone know of the SQL which say if I have a break from one Max to the Min of the next item. E.g. 1-10 12-20 I would like it to return me either the numbers that are missing or at the very least a count or bool if it can detect a break from the Absolute Min and the Absolute Max by going through each range.
SQL Server (MSSQL) 2008
For a database that supports window functions, like Oracle:
SELECT t.*
, CASE LAG(maxq+1, 1, minq) OVER (PARTITION BY prod ORDER BY minq)
WHEN minq
THEN 0
ELSE 1
END AS is_gap
FROM tbl t
;
This will produce is_gap = 1 for a row that forms a gap with the previous row (ordered by minq). If your quantity ranges can overlap, the required logic would need to be provided.
http://sqlfiddle.com/#!4/f609e/4
Something like this, giving max quantities that aren't the overall max for the product and don't have a min quantity following them:
select prev.tbProduct_Id,prev.MaxQuantity
from yourtable prev
left join (select tbProduct_ID, max(MaxQuantity) MaxQuantity from yourtable group by tbProduct_id) maxes
on maxes.tbProduct_ID=prev.tbProduct_Id and maxes.MaxQuantity=prev.MaxQuantity
left join yourtable next
on next.tbProduct_Id=prev.tbProduct_Id and next.MinQuantity=prev.MaxQuantity+1
where maxes.tbProduct_Id is null and next.tbProduct_Id is null;
This would fail on your sample data, though, because it would expect a row with MinQuantity 21, not 20.

How do I set ORDER BY in SQL query to a value depending by the SQL query itself?

Imagine an auction (ebay auction, for example). You create an auction, set the start bidding value, let's say, 5 dollars. This gets stored as a minimal bid value to the auctions table.At this point, the current bid value of this auction is 5 dollars.
Now, if someone bids to your auction, let's say, 10 dollars, this gets stored to the bids table.At this point, the current bid value of this auction is 10 dollars.
Now let's imagine you want to retrieve 5 cheapest auctions. You will write a query like this:
SELECT
`auction_id`,
`auction_startPrice`,
MAX(bids.bid_price) as `bid_price`
FROM
`auctions`
LEFT JOIN `bids` ON `auctions`.`auction_id`=`bids`.`bid_belongs_to_auction`
GROUP BY `auction_id`
LIMIT 5
Pretty simple, and it works! But now you need to add an ORDER BY clause to the query. The problem is, however, that we want to ORDER BY either by auctions.auction_startPrice or by bid_price, depending on whichever of this is higher, as explained in the first paragraphs.
Can this be understood? I know how to do this using 2 queries, but I am hoping it can be done with 1 query.
Thanks!
EDIT: Just a further explanation to help you imagine the problem. If I set ORDER BY auction_startPrice ASC, then I will get 5 auctions with their lowest initial bid price, but what if there are already bids placed on those auctions? Then their current lowest price is equal to those bids, NOT to the start price, therefore my query is wrong.
SELECT
`auction_id`,
`auction_startPrice`,
`bid_price`
FROM
(
SELECT
`auction_id`,
`auction_startPrice`,
MAX(bids.bid_price) as `bid_price`,
IF(MAX(bids.bid_price)>`auction_startPrice`,
MAX(bids.bid_price),
`auction_startPrice`) higherPrice
FROM
`auctions`
LEFT JOIN `bids` ON `auctions`.`auction_id`=`bids`.`bid_belongs_to_auction`
GROUP BY `auction_id`
) X
order by higherPrice desc
LIMIT 5;
Note:
In the inner query, an extra column is created, named 'higherPrice'
The IF function compares the MAX(bid_price) column against the startprice, and only if the Max-bid is not null (implicitly required in comparison) and greater than start price, then the Max-bid becomes the value in the higherPrice column. Otherwise, it will contain the start price.
The outer query merely makes use of the columns from the inner query, ordering by the higherPrice
I'm not sure which database you're using but look at this example:
http://www.extremeexperts.com/sql/articles/CASEinORDER.aspx
SELECT
`auction_id`,
`auction_startPrice`,
MAX(bids.bid_price) as `bid_price`
FROM
`auctions`
LEFT JOIN `bids` ON `auctions`.`auction_id`=`bids`.`bid_belongs_to_auction`
GROUP BY `auction_id`
ORDER BY CASE WHEN `auction_startPrice` > isnull(MAX(bids.bid_price),0) then `auction_startPrice` else MAX(bids.bid_price) end
LIMIT 5

SQL for price difference calculation

I've got two tables that I'm trying to grab data from. The first is a 'titles' table, which represents product information (name, unique ID, etc). The second is a 'prices' table which collects price information for various currencies (each product can have multiple historic entries in the prices table).
I've written a fairly long-winded SQL statement to grab the latest price changes across products, but there are some issues that hopefully more experienced users will be able to help me out with:
SELECT
t.id,
t.name,
t.type,
p.value,
(SELECT
value
FROM
prices
WHERE
prices.id = p.id AND
prices.country='US' AND
prices.timestamp < p.timestamp
ORDER BY
prices.timestamp DESC
LIMIT 1) AS last_value
FROM
prices AS p
INNER JOIN
titles AS t
ON
t.row_id = p.id
WHERE
p.country = 'US' AND
(SELECT
value
FROM
prices
WHERE
prices.id = p.id AND
prices.country='US' AND
prices.timestamp < p.timestamp
ORDER BY
prices.timestamp DESC
LIMIT 1) IS NOT NULL
GROUP BY
t.id
ORDER BY
p.timestamp DESC,
last_value DESC
LIMIT 0, 25"
The first issue I've run into is that, while this query works, titles appear multiple times in the same listing. While this is expected, I'd ideally like only the latest price change to be displayed for the title. To solve this, I tried GROUPING by the titles 'id' (note the: GROUP BY t.id above). Unfortunately, while I'd expect the GROUP to respect the ORDER BY (which orders the latest price changes in DESC order), the results seem to remove the latest changes and show the GROUP'd titles with earlier price values.
Secondly, is there any better way to grab the last price of each item (currently I grab the current value, and then run a subquery to grab the 'last_value' - which effectively represents the value before the current price change). At the moment I run two subqueries: one to grab the second to last known price, and again to ensure that a previous price exists in the database (otherwise there's no point in listing the title as having a price change).
Any help would be appreciated!
How about this:
SELECT titles.id, titles.name, titles.type, prices.value, MAX(prices.timestamp)
FROM titles, prices
WHERE prices.row_id = titles.id AND prices.country='US';
Mind you, I don't have MySQL installed so I couldn't try this query.
[Edit:] I think it won't work 'cause it'll always display the last price entered for all the items because it'll always choose the highest timestamp from the prices table, maybe a group by will do, I'm really sleepy now and I can't think straight;
[Edit2:] How about this:
(SELECT max(report_run_date) as maxdate, report_name
FROM report_history
GROUP BY report_name) maxresults
SELECT titles.id, titles.name, titles.type, prices.value,
(SELECT MAX(prices.timestamp) as maxtimestamp FROM prices GROUP BY prices.row_id)
FROM titles, prices
WHERE prices.row_id = titles.id AND prices.country='US';