How to use Power Query to recreate this SQL OVER PARTITION? - sql

I'm trying to recreate the following logic I create in SQL in Power Query. I'm tried doing it by grouping by the OrderNumber column, but I wasn't able to use a rank function or anything similar. I'm trying to keep the query folding enabled if I can.
SELECT * -- columns
FROM(
SELECT j.*,
rn = ROW_NUMBER() OVER(
PARTITION BY OrderNumber
ORDER BY LineNumber, DateReceived DESC, StatusName DESC
)
FROM [dbo].[Orders] j
) ord
WHERE
ord.rn = 1
Here's a sample of what I'm trying to achieve with this query. I want to rank each order by their LineNumber, in order to select only lowest LineNumber for each order, and in the case of a tie, I use the OrderStatus to determine a winner.

Related

MS SQL add max()-1 to qyery

how to add to the query max(o.Acct)-1 rows. I need to visualize the last two o.Acct rows. My query is currently showing only the max(o.Acct)
SELECT Max(o.Acct) AS [MaxAcct],o.ObjectID,o.Opertype
FROM Operations o
GROUP By o.ObjectID,o.Opertype
If you want to see the last two rows (per group), you're better off using ROW_NUMBER() rather than GROUP BY.
SELECT
*
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ObjectID,
Opertype
ORDER BY Acct DESC
)
AS sequence_id
FROM
Operations
)
sortedOperations
WHERE
sequence_id <= 2
ORDER BY
ObjectID,
Opertype,
Acct
If you want the last two of something, I'm thinking order by and top. Something like this:
select top (2) o.*
from Operations o
order by o.acct desc;

How can I do "SELECT" query with "WHERE" condition on column that does not exist in the table in SQL Server

To understand the question, I'll show an example: my columns in the Students table are:
stuID, cityID, Name, updateDate
and my SELECT is:
SELECT
ROW_NUMBER() OVER (PARTITION BY cityID ORDER BY updateDate DESC) AS rownumber
stuID,
cityID,
Name
FROM
Students
WHERE
rownumber = 1
No matter - why I wish to make such a query, this is only example, but how can I put in the "WHERE" condition on rownumber????
The WHERE Clause will be evaluated immediately after FROM Clause,so SQL has no idea when you refer to somevalue you refered in select
Use CTE/SubQuery if you want to apply predicate to RowNumber :
;With cte
as
(
SELECT
ROW_NUMBER() OVER (PARTITION BY cityID ORDER BY updateDate DESC) AS rownumber
stuID,
cityID,
Name
FROM Students
)
select * from cte where rownumber=1
Below are the logical querying phases which dictates how the clauses defined in one Phase are made available to the clauses in next phases..
1. FROM
2. ON
3.OUTER
4.WHERE
5.GROUP BY
6.CUBE | ROLLUP
7.HAVING
8. SELECT
9. DISTINCT
10. TOP
11. ORDER BY
As you can see ,RowNumber you have defined in select clause which will be available only to next phases after select
Below is the Logical query processing flow chart for each clause :Itzik Ben-Gan
Any aliases and calculated fields are available if you put your query into subquery or CTE:
select *
from
(
SELECT
ROW_NUMBER() OVER (PARTITION BY cityID ORDER BY updateDate DESC) AS rownumber
stuID,
cityID,
Name
FROM Students
) s
WHERE rownumber = 1

How to I do multiple columns partitioning with the rows being duplicated?

I have a set of SQL Stored procedure to use partitioning for my ranking to get percentile. by doing the below partitioning I am able to get my percentiles data right. However my problem is there are duplicates in each row. E.g for each DESC there are multiple duplicates when it is suppose to be only 1 row. Why is this so?
row_nums AS
(
SELECT DATE, DESC, NUM, ROW_NUMBER() OVER (PARTITION BY DATE, DESC ORDER BY NUM ASC) AS Row_Num
FROM ******
)
SELECT .................
This is the output I get currently: (Where there are duplicate rows being returned - Refer to Row 6 to 8)
http://i.stack.imgur.com/foe7g.png[^]
This is the output I want to achieve: http://i.stack.imgur.com/GkrHP.png[^]
You can remove duplicate by adding one more INNER query in FROM clause like below:
;WTIH row_nums AS
(
SELECT DATE, DESC, NUM, ROW_NUMBER() OVER (PARTITION BY DATE, DESC ORDER BY NUM ASC) AS Row_Num
FROM (
SELECT your required columns, COUNT(duplicated_rows_columnsname)
FROM ***
GROUP BY columnnames
HAVING COUNT(duplicated_rows_columnsname) = 1
)
)
SELECT .................
However, You can also remove duplicate row using DISTINCT clause in INNER. query.

Limit result set in sql window function

Assume I would like to rewrite the following aggregate query
select id, max(hittime)
from status
group by id
using an aggregate windowing function like
select id, max(hittime) over(partition by id order by hittime desc) from status
How can I specify, that I am only interested in the first result within the partition?
EDIT: I was thinking that there might be a solution with [ RANGE | ROWS ] BETWEEN frame_start AND frame_end. What to get not only max(hittime) but also the second, third ...
I think what you need is a ranking function, either ROW_NUMBER or DENSE_RANK depending on how you want to handle ties.
select id, hittime
from (
select id, hittime,
dense_rank() over(partition by id order by hittime desc) as ranking
from status
) as x
where ranking = 1; --to get max hittime
--where ranking <=2; --max and second largest
Use distinct statement.
select DISTINCT id, max(hittime) over(partition by id order by hittime desc) from status

Optimizing query with two MAX columns in the same table

I need to optimize below query
SELECT
Id, -- identity
CargoID,
[Status] AS CurrentStatus
FROM
dbo.CargoStatus
WHERE
id IN (SELECT TOP 1 ID
FROM dbo.CargoStatus CS
INNER JOIN STD.StatusMaster S ON CS.ShipStatusID = S.SatusID
WHERE CS.CargoID=CargoStatus.CargoID
ORDER BY YEAR([CS.DATE]) DESC, MONTH([CS.DATE]) DESC,
DAY([CS.DATE]) DESC, S.StatusStageNumber DESC)
There are two tables
CargoStatus, and
StatusMaster
Statusmaster has columns StatusID, StatusName, StatusStageNumber(int)
CargoStatus has columns ID, StatusID (FK StatusMaster StatusID column), Date
Is there any other better way of writing this query.
I want latest status for each cargo (only one entry per cargoID).
Since you seem to be using SQL Server 2005 or newer, you can use a CTE with the ROW_NUMBER() windowing function:
;WITH LatestCargo AS
(
SELECT
cs.Id, -- identity
cs.CargoID,
cs.[Status] AS CurrentStatus
ROW_NUMBER() OVER(PARTITION BY cs.CargoID
ORDER BY cs.[Date], s.StatusStageNumber DESC) AS 'RowNum'
FROM
dbo.CargoStatus cs
INNER JOIN
STD.StatusMaster s ON cs.ShipStatusID = s.[StatusID]
)
SELECT
Id, CargoID, [Status]
FROM
LatestCargo
WHERE
RowNum = 1
This CTE "partitions" your data by CargoID, and for each partition, the ROW_NUMBER function hands out sequential numbers, starting at 1 and ordered by Date DESC - so the latest row gets RowNum = 1 (for each CargoID) which is what I select from the CTE in the SELECT statement after it.