Check Sequence in Max Min Values - sql

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.

Related

SQL Multiple Conditions in max statement not working

I am attempting to filter my table and get the item that sold for the most amount of money. In order to do this I am using "AuctionOpen" to determine whether or not the auction is still open. The auction cannot be open and have the item been sold (later I will use this for the most expensive item available).
I am able to use the AND operator to compare AuctionOpen by using the following:
select s.*
from auctionsite.dbo.Auction s
where s.HighestBid = (select max(s2.HighestBid) from auctionsite.dbo.Auction
s2) and s.AuctionOpen = 0;
When I set this equal to zero I get results, but when I set it equal to 1, it only returns the column titles even though there are values set to 1 in the table.
Results when compared to 0:
Results when compared to 1:
Clearly, the highest bid is on a record where AuctionOpen <> 1.
I recommend using order by and fetch (or the equivalent in your database):
select s.*
from auctionsite.dbo.Auction s
where s.AuctionOpen = 0
order by s.HIghestBid desc
fetch first 1 row only
In SQL Server, use either select top (1) or offset 0 rows fetch first 1 row only.
I think you should try the Count aggregate function
here, try this:
**Select count(Item_name) As
[Item with the highest money]
from table_name
Group by Item_name DSEC;**
You can check my page hereSQL/MySQL tips for some SQL/MySQL lessons

Using a subquery in a where clause to find the second smallest value

I'm trying to find the second smallest value for a list to put it into SSRS as a way to highlight that value. This issue is there are multiple minimum values for a given element. The data is presented such that there is an overarching group A that encompasses smaller groups B and I am wanting the second smallest value for each of the smaller groups.
I have a query set up right now that uses a subquery in the where clause to exclude the minimum value from the search so that the second smallest value will be considered the new minimum value. This seemed to work but the subquery only rules out the minimum value for the larger A group, which may or may not be the minimum value for each B group. Here is my query:
Select
BPosition,
Min(Value) as SecondMinimum
From Table
Where Value > (Select
Min(Value)
From Table
Where APosition = #AName)
and APosition = #AName
Group By BPosition
I was expecting a list of the second smallest values for each B group, but it is pulling in the smallest value in each B group that is greater than the smallest value of the A group. This is right for the one B group that contains the true smallest value but incorrect for the others.
If you want the second largest value, use dense_rank():
Select distinct BPosition, Value as SecondMinimum
From (select t.*,
dense_rank() over (partition by Aposition, Bposition order by value) as seqnum
from table
) t
where seqnum = 2;

Remove Min and Max in group by

I am trying to get a total hours from a dataset and because you can have the same asset with the same company (company_B) twice at two different times I have this join issue. I know I want the min for company_B gone and the Max for company_B gone because they represent wrong dates being matched. The negative is easy but what about the Max?
I have:
AssetID------StartDate-------FinishDate-------CompanyName----HoursOnSite
22222-------2016-02-12-------2016-02-20-------Company_A--------192
22222-------2016-02-01-------2016-02-09-------Company_B--------208 (keep)
22222-------2016-02-12-------2016-02-09-------Company_B-------(-56) (remove)
22222-------2016-02-01-------2016-02-21-------Company_B--------480 (remove)
22222-------2016-02-12-------2016-02-21-------Company_B--------216 (keep)
55555-------2016-02-18-------2016-02-22-------Company_C--------96
99584-------2016-02-22-------2016-02-25-------Company_D--------63
I think you can do the query for the records with max and min HoursOnSite for company B, and use (not in) or not equal to exclude those records.
If you still have concern, please paste your query.
I'm assuming that there has to be atleast 3 instances of unique assetid - companyname combination for the Max, Min filters to work. You can change it in the final where statement tO suit your requirement
WITH CTE
AS (
SELECT *
,count(CompanyName) OVER (PARTITION BY AssetID,CompanyName) AS a
FROM <TABLE_NAME>
)
SELECT *
FROM CTE
WHERE HoursOnSite NOT IN (
SELECT MAX(HoursOnSite)
FROM <TABLE_NAME>
)
AND gdp NOT IN (
SELECT min(HoursOnSite)
FROM <TABLE_NAME>
)
AND a > 2 --MODIFY AS PER YOUR REQUIREMENT

Sql -after group by I need to take rows with newest date

I need to write a query in sql and I can't do it correctly. I have a table with 7 columns 1st_num, 2nd_num, 3rd_num, opening_Date, Amount, code, cancel_Flag.
For every 1st_num, 2nd_num, 3rd_num I want to take only the record with the min (cancel_flag), and if there's more then 1 row so take the the newest opening Date.
But when I do group by and choose min and max for the relevant fields, I get a mix of the rows, for example:
1. 12,130,45678,2015-01-01,2005,333,0
2. 12,130,45678,2015-01-09,105,313,0
The result will be
:12,130,45678,2015-01-09,2005,333,0
and that mixes the rows into one
Microsoft sql server 2008 . using ssis by visual studio 2008
my code is :
SELECT
1st_num,
2nd_num,
3rd_num,
MAX(opening_date),
MAX (Amount),
code,
MIN(cancel_flag)
FROM do. tablename
GROUP BY
1st_num,
2nd_num,
3rd_num,
code
HAVING COUNT(*) > 1
How do I take the row with the max date or.min cancel flag as it is without mixing values?
I can't really post my code because of security reasons but I'm sure you can help.
thank you,
Oren
It is very difficult like this to answer, because every DBMS has different syntax.
Anyways, for most dbms this should work. Using row_number() function to rank the rows, and take only the first one by our definition (all your conditions):
SELECT * FROM (
SELECT t.*,
ROW_NUMBER() OVER ( PARTITION BY t.1st_num,t.2nd_num,t.3rd_num order by t.cancel_flag asc,t.opening_date desc) as row_num
FROM YourTable t ) as tableTempName
WHERE row_num = 1
Use NOT EXISTS to return a row as long as no other row with same 1st_num, 2nd_num, 3rd_num has a lower cancel_flag value, or same cancel_flag but a higher opening_Date.
select *
from tablename t1
where not exists (select 1 from tablename t2
where t2.1st_num = t1.1st_num
and t2.2nd_num = t1.2nd_num
and t2.3rd_num = t1.3rd_num
and (t2.cancel_flag < t1.cancel_flag
or (t2.cancel_flag = t1.cancel_flag and
t2.opening_Date > t1.opening_Date)))
Core ANSI SQL-99, expected to work with (almost) any dbms.

SQL-using CASE in SELECT returns only first case value

I'm using the following query:
SELECT Policy_type_ID,Policy_Value Value,CASE Policy_Value WHEN max(Policy_Value) THEN 'Highest' WHEN min(Policy_Value) THEN 'Lowest' END AS Range
FROM Policy_Types
GROUP BY Policy_type_ID,Policy_Value
HAVING ((Policy_Value IN (SELECT max(Policy_Value)
FROM Policy_Types)) OR (Policy_Value IN(SELECT min(Policy_Value)
FROM Policy_Types)));
But the result has only one value 'Highest' in the column 'Range'.Its only regarding the first case,whichever it maybe, and ignoring the rest.
Policy_type_ID Value Range
501180 990000 Highest
690002 10 Highest
690006 10 Highest
690007 10 Highest
I've no idea where I'm going wrong. Its just that CASE statement that is the problem....any help??
The problem is that your MIN and MAX functions are being calculated within the GROUP BY groups, not across the entire table. You need to calculate them in a separate subquery that doesn't have GROUP BY.
SELECT DISTINCT Policy_type_ID, Policy_Value,
CASE Policy_Value
WHEN MaxPolicy THEN 'Highest'
ELSE 'Lowest'
END Range
FROM Policy_Types
JOIN (SELECT MIN(Policy_Value) MinPolicy, MAX(Policy_Value) MaxPolicy) MinMax
HAVING Policy_Value IN (MinPolicy, MaxPolicy)