Want result with out using subquery? - sql

SELECT
ROW_NUMBER()over(partition by tblProductTemplateHdr.product_ID
order by tblProductTemplateHdr.product_ID, tblProcessSequence.sl_No) AS rno,
tblProductTemplateHdr.product_ID
,tblProductProcessHdr.process_ID
,tblProcessSequence.sl_No
FROM
Production.tblProcessSequence
INNER JOIN
Production.tblProductProcessHdr ON tblProductProcessHdr.product_Process_ID = tblProcessSequence.product_Process_ID AND tblProductProcessHdr.isQC_Need = 1
INNER JOIN
Production.tblProductTemplateHdr ON tblProductTemplateHdr.product_Temp_ID = tblProductProcessHdr.product_Temp_ID
I want the row with maximum sl_No in each product_Id without using a subquery, this the result obtained by running this query want to apply filtering on same query

You need to a) rewrite your query just a little, and b) I'd recommend using table aliases to make your query more readable.
Try this:
;WITH ProductData AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY pth.Product_ID
ORDER BY pth.Product_ID, ps.sl_No DESC) AS rno,
tph.product_ID,
tph.process_ID,
ps.sl_No
FROM
Production.tblProcessSequence ps
INNER JOIN
Production.tblProductProcessHdr pph ON tph.product_Process_ID = ps.product_Process_ID
AND pph.isQC_Need = 1
INNER JOIN
Production.tblProductTemplateHdr tph ON tph.product_Temp_ID = pph.product_Temp_ID
)
SELECT *
FROM
ProductData
WHERE
rno = 1
The ROW_NUMBER() function partitions your data by Product_ID and within each partition, it orders the rows by sl_No DESC - so the highest value of sl_No gets the rno = 1 value (all others get higher numbers, in each partition)

You can use another windowed function:
MAX(tblProcessSequence.sl_No) OVER(PARTITION BY tblProductTemplateHdr.product_ID)
ADDENDUM
Just to give the full query in context in case the above was not clear:
SELECT ROW_NUMBER() OVER (PARTITION BY tempHdr.Product_ID ORDER BY Seq.sl_No DESC) AS rno,
tempHdr.product_ID,
procHdr.process_ID,
Seq.sl_No,
MAX(Seq.sl_No) OVER(PARTITION BY tblProductTemplateHdr.Product_ID) AS Max_SL_No
FROM Production.tblProcessSequence Seq
INNER JOIN Production.tblProductProcessHdr procHdr
ON Seq.product_Process_ID = tblProductProcessHdr.product_Process_ID
AND procHdr.isQC_Need = 1
INNER JOIN Production.tblProductTemplateHdr tempHdr
ON tempHdr.product_Temp_ID = procHdr.product_Temp_ID

Related

SQL Server-How to avoid repetition of a column in the output

Output of my SQL Server Query is as below:
Following is my query:
SELECT
si.SupplyInvoiceID,
si.CompanyID,
si.TotalBill,
siph.BillPaidAmount,
si.TotalBill - SUM(siph.BillPaidAmount)
over( partition by si.SupplyInvoiceID order by siph.SupplyPaymentID asc) as RemainingBillAmount
from
SupplyInvoicePaymentHistory siph
left join
SupplyInvoice si
on siph.SupplyInvoiceID = si.SupplyInvoiceID
I want that in output column TotaBill, bill amount should be shown only one for each SupplyInvoiceID i.e
Required Output
Your problem requires an ordering for the table. It appears to be by SupplyPaymentId (although any column can be used). To do what you want, you can use row_number() and an explicit order by in the query:
select si.SupplyInvoiceID, si.CompanyID,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY si.SupplyInvoiceID order by siph.SupplyPaymentID) = 1
THEN si.TotalBill
END) as TotalBill
siph.BillPaidAmount,
(si.TotalBill -
SUM(siph.BillPaidAmount) over (partition by si.SupplyInvoiceID order by siph.SupplyPaymentID asc)
) as RemainingBillAmount
from SupplyInvoicePaymentHistory siph left join
SupplyInvoice si
on siph.SupplyInvoiceID = si.SupplyInvoiceID
order by si.SupplyInvoiceID, siph.SupplyPaymentID

GROUP BY With ORDER BY ASC & DESC

I have a table, spa, that has most of the information I need:
And I join another table, client, to grab the last_name field:
What I need is to get the first room_code, service_detail, & provider_start_time for each sba_date and provider_code, and the last provider_end_time.
Using my images as examples, the expected result would be:
I think that this can be done with window functions row_number() and last_value():
select
room_code,
service_detail,
sba_date,
provider_start_time,
provider_end_time,
last_name
from (
select
s.*,
c.last_name,
row_number() over(
partition by s.sba_date, s.provider_code
order by s.provider_start_time
) rn,
last_value(provider_end_time) over(
partition by s.sba_date, s.provider_code
order by s.provider_start_time
range between unbounded preceding and unbounded following
) provider_end_time
from spa s
inner join client c on c.client_code = s.provider_code
) t
where rn = 1
The inner query joins the two tables and ranks the records within groups of records having the same sba_date and provider_code, by ascending provider_start_time; it also computes the last value of the provider_end_time within the same group. Then, the outer query filters on the first record in each group.
Also you can use some CTE or sub-query:
;WITH cte AS ( --getting min and max time for particular provider on some date
SELECT sba_date,
MIN(provider_start_time) as provider_start_time,
MAX(provider_end_time) as provider_end_time,
provider_code
FROM spa
GROUP BY sba_date, provider_code
)
-- here goes join to clients (last_name) and original table to get room and detail
SELECT s.room_code,
s.service_detail,
c.sba_date,
c.provider_start_time,
c.provider_end_time,
cl.last_name
FROM cte c
INNER JOIN client cl
ON c.provider_code = cl.client_code
INNER JOIN spa s
ON s.sba_date = c.sba_date0
AND s.provider_code = c.provider_code
AND s.provider_start_time = c.provider_start_time

Include join in a subquery

I trying to make a query to obtain the last date time when a records repeat.
select * from OCCONTROLMERCADERIA om
join OCCONTROLMERCADERIALINEAS oml on om.occontrolid=oml.occontrolid
where om.OCControlNroId=5519337
This return this:
Result Query 1
The query that i want should return the register are in the blue box.
I have this query that found (without the join):
with
p as (select * from OCCONTROLMERCADERIA om where om.OCControlNroId=5519337),
p_rnk as (
select *, row_number() over (partition by OCControlNroId order by OCControlFecha desc) as rn
from p
)
select * from p_rnk where rn = 1 order by OCControlNroId;
This return this:
Result Query 2
That its ok, if see the box blue in the first image, the last date corresponds to the record id 13756.
But I need that the query return the 3 records that corresponds to id 13756, and not only one, so i trying to apply the join.
with
p as (select * from OCCONTROLMERCADERIA om
join OCCONTROLMERCADERIALINEAS oml on om.occontrolid=oml.occontrolid
where om.OCControlNroId=5519337),
p_rnk as (
select *, row_number() over (partition by OCControlNroId order by OCControlFecha desc) as rn
from p
)
select * from p_rnk where rn = 1 order by OCControlNroId;
But this return:
The column 'OCControlId' was specified multiple times for 'p'.
I´m trying this (select om.*):
with
p as (select om.* from OCCONTROLMERCADERIA om
join OCCONTROLMERCADERIALINEAS oml on om.occontrolid=oml.occontrolid
where om.OCControlNroId=5519337),
p_rnk as (
select *, row_number() over (partition by OCControlNroId order by OCControlFecha desc) as rn
from p
)
select * from p_rnk where rn = 1 order by OCControlNroId;
And the error disappears but only return one records, no the three. Which could the problem ?
Thanks for your help!

Oracle, get top row using order by desc and rownum

This query gives me invalid identifier error, and i know it is because subquery will only be able to access data that is one layer higher.
select *
from t2_callerid_plan cp
where cp.subsrefnum in (
select *
from (
select vsap.subsrefnum
from prv_internet_responses_vsap vsap
where vsap.subsrefnum = cp.subsrefnum
order by vsap.id desc
)
where rownum = 1
);
Now, i was wandering if there is way i can create query that would be able to return only the newest row while using the data from query in subquery?
You can use ROW_NUMBER() :
SELECT * FROM (
SELECT cp.*,
ROW_NUMBER() OVER(PARTITION BY cp.subsrefnum ORDER BY vsap.id desc) as rnk
from t2_callerid_plan cp
JOIN prv_internet_responses_vsap vsap
ON vsap.subsrefnum = cp.subsrefnum) p
WHERE p.rnk = 1
you can try this:
select *
from t2_callerid_plan cp
inner join
(
select vsap.subsrefnum,ROW_NUMBER() OVER (PARTITION BY subsrefnum ORDER BY vsap.id desc) rn
from prv_internet_responses_vsap vsap
)vsap
on vsap.subsrefnum = cp.subsrefnum and vsap.rn=1

(SQL Server) using row count to sort the list but dont need list out the row count number

All the column that inside the select sql are needed to list out ,except the row_number(),any solution to eliminate to row_count ?
SELECT *
FROM
(SELECT Station,
ROW_NUMBER() over (
ORDER BY totalseq ASC) AS rownumber1
FROM [SFCKM].[dbo].[T_DB_Subline]
WHERE Track_Point_No = '3d1')a
LEFT JOIN
(SELECT group_no,
trim_line,
MSC,
lot_no,
color,
AON,
format(Commit_time,'MM/dd/yy h:mm:ss tt')AS time,
datediff(DAY,Commit_Time,SYSDATETIME()) AS aging,
ROW_NUMBER() over (
ORDER BY commit_time DESC) AS rownumber
FROM [SFCKM].[dbo].[T_Work_Actual]
WHERE Track_Point_No = '3d1') c ON a.rownumber1 = c.rownumber
ORDER BY a.rownumber1
You could just select the values you are looking for e.g. Station and aging.
select a.Station, c.aging from
(select Station, ROW_NUMBER() over (order by totalseq asc) AS rownumber1
from [SFCKM].[dbo].[T_DB_Subline] where Track_Point_No = '3d1') a
left join
(*,aging,ROW_NUMBER() over (order by commit_time desc) AS rownumber
FROM [SFCKM].[dbo].[T_Work_Actual] where Track_Point_No = '3d1') c
on a.rownumber1 = c.rownumber
order by a.rownumber1
Don't use SELECT *: specify only the columns you need. SELECT * is not best practice, just lazy
There is no way to exclude a column as per my answer SQL exclude a column using SELECT * [except columnA] FROM tableA?