how to get the latest price in sql query - sql

I need get the price of lasted QuoteDate.
Right now i have query like these
SELECT dbo.INMT.Material, dbo.INMT.LastVendor, dbo.INMT.AvgCost, dbo.MSQD.Status, dbo.MSQH.QuoteDate, dbo.MSQD.UnitPrice
FROM dbo.INMT INNER JOIN
dbo.MSQD ON dbo.INMT.MatlGroup = dbo.MSQD.MatlGroup AND dbo.INMT.Material = dbo.MSQD.Material INNER JOIN
dbo.MSQH ON dbo.MSQD.MSCo = dbo.MSQH.MSCo AND dbo.MSQD.Quote = dbo.MSQH.Quote
GROUP BY dbo.INMT.Material, dbo.INMT.LastVendor, dbo.INMT.AvgCost, dbo.MSQD.Status, dbo.MSQD.UnitPrice, dbo.MSQH.QuoteDate
ORDER BY dbo.INMT.Material
and get the following result
and how can i run a query just get the highlighted record.i try to do something like where QuoteDate =max......but maybe my grouyping is not correct.
thanks

So, assuming SQL Server 2005+, you can use a CTE and ROW_NUMBER():
;WITH CTE AS
(
SELECT I.Material,
I.LastVendor,
I.AvgCost,
MD.Status,
MH.QuoteDate,
MD.UnitPrice,
RN = ROW_NUMBER() OVER( PARTITION BY I.Material, I.LastVendor,
I.AvgCost, MD.Status,
MD.UnitPrice
ORDER BY MH.QuoteDate DESC)
FROM dbo.INMT I
INNER JOIN dbo.MSQD MD
ON I.MatlGroup = MD.MatlGroup
AND I.Material = MD.Material
INNER JOIN dbo.MSQH MH
ON MD.MSCo = MH.MSCo
AND MD.Quote = MH.Quote
)
SELECT Material,
LastVendor,
AvgCost,
Status,
QuoteDate,
UnitPrice
FROM CTE
WHERE RN = 1

Use HAVING QuoteDate=max... after the order by clause.

Related

SQL Server aggregate function without group by

I want to include tcon.Inductive_Injection_Hours, tcon.Capacitive_Injection_Hours without applying group by. How can I do that?
SELECT
bp.Serial_Number,
tcon.Serial_Number AS ConverterSerialNumber,
MAX(tcon.Time_Stamp) AS DateStamp,
tcon.Inductive_Injection_Hours,
tcon.Capacitive_Injection_Hours
FROM
dbo.Bypass AS bp
INNER JOIN
dbo.Converter AS c ON bp.Bypass_ID = c.Bypass_ID
INNER JOIN
dbo.Converter_Tel_Data AS tcon ON c.Converter_ID = tcon.Converter_ID
WHERE
(bp.Site_ID = 7)
GROUP BY
bp.Serial_Number, tcon.Serial_Number,
tcon.Inductive_Injection_Hours, tcon.Capacitive_Injection_Hours
ORDER BY
ConverterSerialNumber
I have figured it out.
select [data].Serial_Number,Time_Stamp,Inductive_Injection_Hours,Capacitive_Injection_Hours,b.Serial_Number from Converter_Tel_Data as [data]
inner join dbo.Converter AS c On [data].Converter_ID = c.Converter_ID
inner join dbo.Bypass as b on c.Bypass_ID = b.Bypass_ID
WHERE
(Time_Stamp = (SELECT MAX(Time_Stamp) FROM Converter_Tel_Data WHERE Converter_ID = [data].Converter_ID)) And ([data].Site_ID=7)
ORDER BY [data].Serial_Number
You can use row_number - either in a CTE/derived table or using a trick with TOP 1.
Select Top 1 With Ties
bp.Serial_Number
, tcon.Serial_Number AS ConverterSerialNumber
, tcon.Time_Stamp AS DateStamp
, tcon.Inductive_Injection_Hours
, tcon.Capacitive_Injection_Hours
From dbo.Bypass AS bp
Inner Join dbo.Converter AS c On bp.Bypass_ID = c.Bypass_ID
Inner Join dbo.Converter_Tel_Data AS tcon ON c.Converter_ID = tcon.Converter_ID
Where bp.Site_ID = 7
Order By
row_number() over(Partition By bp.Serial_Number Order By tcon.Time_Stamp desc)
This should return the latest row from the tconn table for each bp.Serial_Number.

How to optimize this T-sql query?

There is a loop in this query, in the last where condition. and this
causes a severe problem to the performance of SQL.
I have no idea about how to modify it.
select pr.tavpun
from mta110 pr
where pr.taisoc = mta110.taisoc
and pr.taitar = mta110.taitar
and pr.taydat = mta110.taydat
and pr.tairef = mta110.tairef
and pr.tatind = (select max(pr2.tatind) from mta110 pr2
where pr2.taisoc = mta110.taisoc
and pr2.taitar = mta110.taitar
and pr2.taydat = mta110.taydat
and pr2.tairef = mta110.tairef
and pr2.tatind <= mgc100.gntind)) AS SalesPrice
Your query makes little sense, because pr is not a reasonable alias for mta110, and mta110 is not recognized in the outer query.
I speculate that you have two tables, pr and mta110 which are joined and you want the "most recent" row of mta110 for each matching row.
If this interpretation is correct, then you can use row_number() and a proper join:
select . . .
from pr join
(select m.*,
row_number() over (partition by taisoc, taitar, taydat, tairef order by gntind desc) as seqnum
from mta110 m
) m
on pr.? = m.?
where seqnum = 1;

SQL Last DateTime value

I am trying to query some 'job' databases where I need the last datetime value for each operation_service in a given job. I also need to know whether the operation is complete or not.
SELECT Job.Job, Job_Operation.Operation_Service, Job_Operation.Sequence,
MAX(Job_Operation_Time.Last_Updated) AS 'Last_Updated', Job_Operation_Time.Operation_Complete
FROM Job_Operation
LEFT JOIN Job ON Job.Job = Job_Operation.Job
LEFT JOIN Job_Operation_Time ON Job_Operation_Time.Job_Operation = Job_Operation.Job_Operation
WHERE Job.Status = 'Active'
GROUP BY Job.Job, Job_Operation.Operation_Service, Job_Operation.Sequence, Job_Operation_Time.Last_Updated, Job_Operation_Time.Operation_Complete
ORDER BY Job.Job, Sequence
A snippet of some results here:
What I would like is a query that returns all the highlighted records but does not return the records with a red line through the job field. NULL values are possible for both Operation_Complete and Last_Updated.
use row_number()
with cte as
(
SELECT Job.Job, Job_Operation.Operation_Service, Job_Operation.Sequence,
(Job_Operation_Time.Last_Updated) AS 'Last_Updated', Job_Operation_Time.Operation_Complete
,row_number()over(partition by Job_Operation.Operation_Service order by Job_Operation_Time.Last_Updated desc) rn
FROM Job_Operation
LEFT JOIN Job ON Job.Job = Job_Operation.Job
LEFT JOIN Job_Operation_Time ON Job_Operation_Time.Job_Operation = Job_Operation.Job_Operation
WHERE Job.Status = 'Active'
) select * from cte where rn=1

First event per patients

The attached code is supposed to return the first ORDER_PROC.ORDER_INST for each patient. I'm getting multiple records in some cases.
Any suggestions on a better approach?
Thanks
Steve
SELECT DISTINCT
ORDER_PROC.PAT_ENC_CSN_ID as ordercsn, Min(ORDER_PROC.ORDER_INST) as
CodeStatus_Datetime, CLARITY_SER.PROV_NAME as CodeStatus_OrderProvider
FROM
ORDER_PROC with(nolock) , ORDER_METRICS with(nolock) , CLARITY_SER
with(nolock)
WHERE
ORDER_PROC.ORDER_PROC_ID = ORDER_METRICS.ORDER_ID AND
ORDER_METRICS.ORDERING_PROV_ID = CLARITY_SER.PROV_ID AND
--ORDER_PROC.REASON_FOR_CANC_C IS NULL AND
(ORDER_PROC.PROC_CODE = 'COD1' OR
ORDER_PROC.PROC_CODE = 'COD2' OR
ORDER_PROC.PROC_CODE = 'COD3'
)
GROUP by
ORDER_PROC.PAT_ENC_CSN_ID, ORDER_PROC.ORDER_INST,CLARITY_SER.PROV_NAME
Use ROW_NUMBER() to create partition for each patient
SELECT *
FROM (
SELECT OP.PAT_ENC_CSN_ID as ordercsn,
OP.ORDER_INST,
CodeStatus_Datetime,
CS.PROV_NAME as CodeStatus_OrderProvider,
ROW_NUMBER() OVER (PARTITION BY OP.PAT_ENC_CSN_ID
ORDER BY OP.ORDER_INST) as rn
FROM ORDER_PROC OP
JOIN ORDER_METRICS OM
OP.ORDER_PROC_ID = OM.ORDER_ID
JOIN CLARITY_SER CS
OM.ORDERING_PROV_ID = CS.PROV_ID
WHERE
OP.PROC_CODE IN ('COD1','COD2','COD3')
) as T
WHERE rn = 1

most frequent occurence

I have a table with transactions and a statement that is giving out the most used creditcards. AMEX, VISA ...
SELECT CARDBRAND,
count(*) as cardused
from INFO c
left join paytb t
on c.CONT_ID = t.CONT_ID
GROUP BY CARDBRAND
ORDER BY 2 desc;
Now I want to add a column with the MERCHNAME of the shops that were most often found in a transaction with the creditcard:
CARDBRAND CARDUSED MERCHNAME
----------------------------------------
AMEX 182345 Gasstation
VISA 70943 ....
SELECT CARDBRAND
,count(*) as cardused
,MERCHNAME
FROM INFO c
LEFT JOIN paytb t
on c.CONT_ID = t.CONT_ID
GROUP BY CARDBRAND,
MERCHNAME
ORDER BY count(*) desc;
suggestion: It is always recommended to use the ColumnName or function in this case in the ORDERBY clause rather than the column number to avoid any confusion.
First, your correct query should be:
select c.cardbrand, count(t.cont_id) as cardused
from info c left join
paytb t
on c.cont_id = t.cont_id
group by c.cardbrand;
Otherwise, you will never get "0" for card brands that are not used.
For the merchant information, you can use window functions:
select cardbrand, total_cardused, merchant
from (select c.cardbrand, t.merchant, count(t.cont_id) as cardused,
sum(count(t.cont_id)) over (partition by c.cardbrand) as total_cardused,
row_number() over (partition by c.cardbrand order by count(t.cont_id) desc) as seqnum
from info c left join
paytb t
on c.cont_id = t.cont_id
group by c.cardbrand, t.merchant
) cm
where seqnum = 1
group by c.cardbrand;