SQL Query Assistance (ObjectPropertyvalue) - sql-server

[![enter image description here][1]][1]I need help with the following query.
select *
from xr.ObjectPropertyvalue
where objectid in (
select objectid
from xr.objectpropertyvalue
where endversion in
(select max(endversion)
from xr.ObjectPropertyValue
group by objectid having count(endversion) > 1
)
)
What I was trying to do is to look for an entry on the table that has the highest end version and the objectid being unique.
Ex.
Object id 1's highest version = 3
Object id 2 highest version =4
Any help would be appreciated.

If I understood correctly, you may try this query (un-tested, I don't have sql-server environment now)
WITH cte AS (
SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY objectid ORDER BY endversion DESC)
FROM xr.ObjectPropertyvalue
)
SELECT *
FROM cte c
WHERE c.rn = 1
AND EXISTS (SELECT 1 FROM cte c2 WHERE c2.objectid = c.objectid AND c2.rn = 2)
ORDER BY c.objectid

Related

SQL select the row with max value using row_number() or rank()

I have data of following kind:
RowId Name Value
1 s1 12
22 s1 3
13 s1 4
10 s2 14
22 s2 5
3 s2 100
I want to have the following output:
RowId Name Value
1 s1 12
3 s2 100
I am currently using temp tables to get this in two step. I have been trying to use row_number() and rank() functions but have not been successful.
Can someone please help me with syntax as I feel row_number() and rank() will make it cleaner?
Edit:
I changed the rowId to make it a general case
Edit:
I am open to ideas better than row_number() and rank() if there are any.
If you use rank() you can get multiple results when a name has more than 1 row with the same max value. If that is what you are wanting, then switch row_number() to rank() in the following examples.
For the highest value per name (top 1 per group), using row_number()
select sub.RowId, sub.Name, sub.Value
from (
select *
, rn = row_number() over (
partition by Name
order by Value desc
)
from t
) as sub
where sub.rn = 1
I can not say that there are any 'better' alternatives, but there are alternatives. Performance may vary.
cross apply version:
select distinct
x.RowId
, t.Name
, x.Value
from t
cross apply (
select top 1
*
from t as i
where i.Name = t.Name
order by i.Value desc
) as x;
top with ties using row_number() version:
select top 1 with ties
*
from t
order by
row_number() over (
partition by Name
order by Value desc
)
This inner join version has the same issue as using rank() instead of row_number() in that you can get multiple results for the same name if a name has more than one row with the same max value.
inner join version:
select t.*
from t
inner join (
select MaxValue = max(value), Name
from t
group by Name
) as m
on t.Name = m.Name
and t.Value = m.MaxValue;
If you really want to use ROW_NUMBER() you can do it this way:
With Cte As
(
Select *,
Row_Number() Over (Partition By Name Order By Value Desc) RN
From YourTable
)
Select RowId, Name, Value
From Cte
Where RN = 1;
Unless I'm missing something... Why use row_number() or rank?
select rowid, name, max(value) as value
from table
group by rowid, name

Select highest value in a column with other column values SQL Server

My table looks like this:
And I want to get highest bid amount for a specific product, with the row id. My query is like this
SELECT
MAX(BidAmount) as highestBid,id
FROM
[wf_bid]
WHERE
ProductId = 101 AND ClientId = 101
GROUP BY
id
I expect only one row with highest BidAmount, but the query returns all rows with this product id and client id. How can I fix this issue?
How about sub-query ? If you have multiple records with same BidAmount, then it return top 1.
SELECT TOP 1
BidAmount as highestBid,id
FROM [wf_bid] WHERE BidAmount = (Select Max(BidAmount) FROM [wf_bid] WHERE ProductId=101 and ClientId=101)
You can use row_number() and select the first row:
SELECT *
FROM
(
SELECT
id,
BidAmount,
ROW_NUMBER() OVER (ORDER BY BidAmount desc) as rn
FROM
[wf_bid]
WHERE ProductId = 101 and ClientId = 101
) i
WHERE
i.rn = 1
How about this way:
SELECT id,highestBid from
(Select Max(BidAmount)highestBid,productID,clientid FROM [wf_bid] WHERE ProductId=101 and ClientId=101) a
LEFT JOIN
(SELECT id,productID,clientid FROM [wf_bid]) as b
where a.productID = b.productid and a.clientid = b.clientid
try this way,
select * FROM
(SELECT
id,
BidAmount,
ROW_NUMBER() OVER (parrtition by ProductId ORDER BY BidAmount desc) as rn
FROM
[wf_bid]
WHERE ClientId = 101)t4
where rn=1
Your problem is in the group by ID, it doesn't work that way because it isn't "adding your bids" it is telling you the max number of every ID not just which is the biggest bid and it's ID. I'm guessing you'll get what you want if you delete group by id. If not you would need to explain your need further.

How to extract the last records based on entrydate sql server

i have many duplicate job id but entry date is can not be duplicate. i need to fetch always unique job id based on last entry date. i have solved it with the below query but like to know is there any better way to form the same sql when data would be huge for best performance. please guide me thanks.
SELECT A.JID,A.EntryDate,RefundDate,Comments,Refund, ActionBy
FROM (
(
select JID, Max(EntryDate) AS EntryDate
from refundrequested
GROUP BY JID
) A
Inner JOIN
(
SELECT JID,ENTRYDATE,refundDate,Comments,refund,ActionBy
from refundrequested
) B
ON A.JID=B.JID AND A.EntryDate = B.EntryDate
)
Using the row_number() function is usually a bit faster:
select *
from (
select row_number() over (partition by jid
order by EntryDate desc) as rn
, *
from refundrequested
) as SubQueryAlias
where rn = 1
Query:
SELECT t1.JID,
t1.EntryDate,
t1.RefundDate,
t1.Comments,
t1.Refund,
t1.ActionBy
FROM refundrequested t1
LEFT JOIN refundrequested t2
ON t2.JID = t1.JID
AND t2.EntryDate > t1.EntryDate
WHERE t2.JID is null

Subtract top two rows from one column using one id

does anyone know how can I subtract top two rows from one column only using one id? Here's my sample query:
SELECT top 2 a.consumption,
coalesce(a.consumption -
(SELECT b.consumption
FROM tbl_t_billing b
WHERE b.id = a.id + 1), a.consumption) AS diff
FROM tbl_t_billing a
WHERE a.customerId = '5'
ORDER BY a.dateCreated DESC
I want to know how to get the difference between the top 2 rows using one id from the consumption column using the customerId #5. I've tried but I can't get the right query for that. Can somebody help me please? Thanks!
try this:
;with cte as
(
select consumption, customerId,
row_number() over (partiton by customerid order by datecreated desc) rn
from tbl_t_billing where customerId = '5'
)
select a.customerId, a.consumption,
coalesce((a.consumption - b.consumption), a.consumption) consumption_diff
from cte a left outer join cte b on a.rn + 1 = b.rn
where a.rn = 1
declare #tbl_t_billing table(consumption int, customerId int, datecreated datetime)
insert into #tbl_t_billing
values
(10,5,'20100101'),
(7,5,'20000101'),
(9,4,'20100101'),
(5,4,'20000101'),
(8,3,'20100101'),
(3,3,'20000101'),
(7,2,'20100101'),
(3,2,'20000101'),
(4,1,'20100101'),
(2,1,'20000101')
-- get the difference between the last two consumption values for each customerId
select
customerId,
sum(consumption) diff
from(
select
customerId,
consumption *
case row_number() over(partition by customerId order by datecreated desc)
when 1 then 1 when 2 then -1
end consumption
from #tbl_t_billing
) t
group by customerId

Return 5 Newest Articles for Each Category in MS SQL Server

Let's say I have a table Articles on a SQL Server 2008 database with the columns ID INT, Title VARCHAR(100), CatID INT, Posted DATETIME.
To get the 5 newest articles for a particular category, I can do this.
SELECT TOP (5) * FROM Articles WHERE CatID = #CatID ORDER BY Posted DESC
But what if I want the 5 newest articles for each category? I know I can repeat the query above for each category, but is there any way to do a single query that will return the 5 newest articles for each category?
EDIT:
Here's is the actual query I'm using to return the 5 newest articles with the section #SectionID. According to the actual terminology I'm using, it's the "section" I'm grouping by, not "category".
SELECT TOP (5) *
FROM Article
INNER JOIN Subcategory on Article.ArtSubcategoryID = Subcategory.SubID
INNER JOIN Category on Subcategory.SubCatID = Category.CatID
INNER JOIN section ON Category.CatSectionID = Section.SecID
WHERE (Section.SecID = #SectionID)
ORDER BY Article.ArtUpdated DESC
EDIT 2:
And here's the query I came up with based on comments here. Seems to work okay.
SELECT *
FROM (
SELECT Article.*,
ROW_NUMBER() OVER (PARTITION BY SecID ORDER BY ArtUpdated DESC) AS rn
FROM Article
INNER JOIN Subcategory on Article.ArtSubcategoryID = Subcategory.SubID
INNER JOIN Category on Subcategory.SubCatID = Category.CatID
INNER JOIN section ON Category.CatSectionID = Section.SecID
) q
WHERE rn <= 5
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CatId ORDER BY Posted DESC) AS rn
FROM Articles
) q
WHERE rn <= 5
Try this
;WITH CTE AS (SELECT ROW_NUMBER() OVER(PARTITION BY CatID ORDER BY Posted DESC)
AS Rownum,*
FROM Articles )
SELECT * FROM CTE WHERE Rownum <= 5

Resources