What will be the query for this? - sql

JOIN public.match m ON (s.stadium_id = m.stadium_id)
group
AS (
)
SELECT round_number
,stadium_name
,spectators
FROM (
SELECT round_number
,stadium_name
,spectators
,RANK() OVER (
PARTITION BY round_number ORDER BY spectators DESC
) AS rank1
FROM t1
) AS s1
WHERE rank1 = 1
<br>
Any smaller query than this?

I think you can just use window functions:
select ms.*
from (select m.round_number, s.stadium_name, m.no_spectators,
row_number() over (partition by m.round_number order by m.no_spectators desc) as seqnum
from public.stadium s join
public.match m
on s.stadium_id = m.stadium_id
) ms
where seqnum = 1
order by m.round_number;
I don't see why aggregation would be needed for the inner query.

You can use a subquery to get the max first
select m.round_number, s.stadium_name, MaxSpec
from public.stadium s
JOIN public.match m ON (s.stadium_id = m.stadium_id)
JOIN
(
select m.round_number, MAX(m.no_spectators) as MaxSpec
from public.stadium s
JOIN public.match m ON (s.stadium_id = m.stadium_id)
group by m.round_number
)a on m.no_spectators = a.MaxSpec

Just one more way to skin this cat. Throw your MAX(no_spectators) into a WHERE clause.
SELECT
m.round_number,
s.stadium_name,
m.no_spectators
FROM
PUBLIC.stadium s
JOIN
PUBLIC.match m
ON s.stadium_id = m.stadium_id
WHERE
m.no_spectators = (SELECT MAX(no_spectators) FROM PUBLIC.match);
That should do for an intro class.

Related

I need to only select the minimum value of my query

I have a view created in SQL Server Management Studio that brings in certain data, I need to only select the rows with the minimum sequence. For example, in the screenshot see the job number "50773-4", I would only need to see the row with SEQ number 2. I've tried to Group by Min, but to no avail. Any help would be appreciated.
SELECT
TOP (100) PERCENT dbo.Job_Operation.Job,
MIN(dbo.Job_Operation.Sequence) AS SEQ,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
GROUP BY
dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
HAVING
(dbo.Work_Center.UVText4 = 'Machining')
ORDER BY
dbo.User_Values.Decimal1 DESC,
SEQ
[enter image description here]
I would try the RANK() window function. Perhaps:
SELECT column1,
column2,
rank() OVER (PARTITION BY job ORDER BY seq) AS seq_by_job
Then use this as a nested statement, and filter on only the min rank (i.e. WHERE nested_statement.seq_by_job = 1)
here is one way :
SELECT
TOP (100) PERCENT Job,
Sequence AS SEQ,
Work_Center,
Department
FROM
( select dbo.Job_Operation.Job,
dbo.Job_Operation.Sequence,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department,
dbo.User_Values.Decimal1 ,
ROW_NUMBER() over (partition by dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
Order by dbo.Job_Operation.Sequence asc) rn
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
) tt
WHERE rn = 1
and UVText4 = 'Machining'
You can do:
with
q as (
SELECT
dbo.Job_Operation.Job,
MIN(dbo.Job_Operation.Sequence) AS SEQ,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department,
dbo.User_Values.Decimal1
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values
ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center
ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
GROUP BY
dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
HAVING
(dbo.Work_Center.UVText4 = 'Machining')
),
r as (
select *,
row_number() over(partition by job order by seq) as rn
from q
)
select job, seq, work_center, department
from r
where rn = 1
order by Decimal1 DESC

Join with max improve query

select Tf.*
from SalesOrder SO
join TransportOrder Tf on Tf.SalesOrderID = SO.SalesOrderID
join (
select Sz.TradingPartner, Sz.ExternalSalesOrder, Tz.TransportOrderNumber, max(Tz.Revision) Revision
from SalesOrder Sz
join TransportOrder Tz on Sz.SalesOrderID = Tz.SalesOrderID
group by Sz.TradingPartner, Sz.ExternalSalesOrder, Tz.TransportOrderNumber
) TU on TU.TradingPartner = SO.TradingPartner and TU.ExternalSalesOrder = SO.ExternalSalesOrder and TU.TransportOrderNumber = Tf.TransportOrderNumber and Tf.Revision = TU.Revision
I want to know If I can improve it?
What I want to do:
select the TransportOrders that have the maximum revision.
a transport order can be identified with salesOrder.TradingPartner, salesOrder.ExternalSalerOrder, transportOrder.TransportOrderNumer and transportOrder.Revision (used as a version field)
so I want all the transportorder with last version
You can use the ROW_NUMBER analytical function as follows:
SELECT * FROM
(SELECT TF.*,
ROW_NUMBER()
OVER (PARTITION BY SZ.TRADINGPARTNER,
SZ.EXTERNALSALESORDER,
TZ.TRANSPORTORDERNUMBER
ORDER BY TZ.REVISION DESC) AS RN
FROM SALESORDER SO
JOIN TRANSPORTORDER TF
ON TF.SALESORDERID = SO.SALESORDERID
JOIN SALESORDER SZ
ON SZ.TRADINGPARTNER = SO.TRADINGPARTNER
AND SZ.EXTERNALSALESORDER = SO.EXTERNALSALESORDER
JOIN TRANSPORTORDER TZ
ON SZ.SALESORDERID = TZ.SALESORDERID
AND TRANSPORTORDERNUMBER = TF.TRANSPORTORDERNUMBER
)
WHERE TF.REVISION = TU.REVISION
I would suggest window functions
select st.*
from (select t.*, so.TradingPartner, so.ExternalSalerOrder,
max(t.revision) over (partition by so.TradingPartner, so.ExternalSalerOrder, t.TransportOrderNumber) as max_revision
from SalesOrder SO join
TransportOrder t
on t.SalesOrderID = so.SalesOrderID
) st
where revision = max_revision;
No need to reopen the two tables. You can use window functions like this:
select *
from (
select t.*,
rank() over(
partition by s.TradingPartner, s.ExternalSalerOrder, t.TransportOrderNumer
order by t.Revision desc
) rn
from SalesOrder s
join TransportOrder t on t.SalesOrderID = s.SalesOrderID
) t
where rn = 1

HIDE Column in Select query?

Hi I'm trying to hide the TotalRank Column that gets displayed during my results because I only needed it in this query to help sort items. I don't need this information displayed.
SELECT TOP 15 G.CharacterName, G.JobCode, G.PvPExp, D.PVPWin, D.PVPLose, D.PVPGiveUp, RANK() OVER (ORDER BY TotalRank ASC ) as TotalRank
FROM PvPRanking as G
INNER JOIN PVPScores as D
ON G.CharacterID = D.CharacterID
You can use th following
SELECT TOP 15 G.CharacterName, G.JobCode, G.PvPExp, D.PVPWin, D.PVPLose, D.PVPGiveUp
FROM PvPRanking as G
INNER JOIN PVPScores as D
ON G.CharacterID = D.CharacterID
ORDER BY RANK() OVER (ORDER BY TotalRank ASC )
You can create and alias to the resulting table and select everything from it except for the total rank column.
SELECT t1.CharacterName, t1.JobCode, t1.PvPExp, t1.PVPWin, t1.PVPLose, t1.PVPGiveUp
FROM
(SELECT TOP 15 G.CharacterName, G.JobCode, G.PvPExp, D.PVPWin, D.PVPLose, D.PVPGiveUp,
RANK() OVER (ORDER BY TotalRank ASC ) as TotalRank
FROM PvPRanking as G
INNER JOIN PVPScores as D
ON G.CharacterID = D.CharacterID) AS t1

Joined 3 Tables in SQL and Getting duplicated records

I have 3 tables and trying to get the data out without having many duplicates. Please check on the image that I sent. This is the desired result. Thanks.
I tried:
EDIT:
All this does is Grab all records from Parts then all the records from Assemblies then all the records in Materials. So the return records is HUGE. Here is the standard SQL Statement that connects these tables together.
SELECT impPartID, impShortDescription, uimpConfigPartID as ConfigID,
imaPartID, immPartID FROM Parts
Left Outer Join PartAssemblies on IMAMETHODID = IMPPARTID and
IMAPARENTASSEMBLYID = 0
Left Outer Join PartMaterials on IMMMETHODID = IMPPARTID and
IMMMETHODASSEMBLYID = 0
So I tried this
Select p.impPartID, p.impShortDescription, p.uimpConfigPartID as ConfigID,
a.imaPartID as Assem, m.immPartID as Materials
from (select p.*, row_number() over (order by (select null)) as seqnum
from parts p where uimpConfigPartID <> ''
) p full join
(select a.*, row_number() over (order by (select null)) as seqnum
from assemblies a
) a
on a.IMAMETHODID = p.impPartID and a.seqnum = p.seqnum full join
(select m.*, row_number() over (order by (select null)) as seqnum
from materials m
) m
on m.IMMMETHODID = coalesce(a.IMAMETHODID, p.impPartID) and
m.seqnum = coalesce(a.seqnum, p.seqnum)
One method uses row_number(), union all and group by:
select p.partid, a.descassembly, m.descmaterial
from (select p.*, row_number() over (order by (select null)) as seqnum
from parts p
) p full join
(select a.*, row_number() over (order by (select null)) as seqnum
from assemblies a
) a
on a.partid = p.partid and a.seqnum = p.seqnum full join
(select m.*, row_number() over (order by (select null)) as seqnum
from materials m
) a
on m.partid = coalesce(a.partid, p.partid) and
m.seqnum = coalesce(a.seqnum, p.seqnum);

How would that be possible to make this SQL Query simpler/shorter?

It should return some fields from the SystemTable and the LoadStatus column of the latest record in the ProcessHistory table. The relationship is 1 to many:
SELECT ST.[SystemDetailID], ST.[SystemName], LH.LatestLoadStatus
FROM [SystemTable] AS ST
LEFT OUTER JOIN
(
SELECT LHInner.LoadStatus AS LatestLoadStatus, LHInner.SystemDetailID FROM [dbo].[LoadHistory] AS LHInner
WHERE LHInner.LoadHistoryID in
(
SELECT LatestLoadHisotoryID FROM
(
SELECT MAX(LoadHistoryID) as LatestLoadHisotoryID, SystemDetailID FROM [dbo].[LoadHistory]
GROUP BY SystemDetailID
) l
)
) AS LH ON ST.SystemDetailID = LH.SystemDetailID
Thanks,
This is a greatest-n-per-group query.
One Approach
SELECT ST.[SystemDetailID],
ST.[SystemName],
LH.LatestLoadStatus
FROM [SystemTable] AS ST
OUTER APPLY (SELECT TOP 1 *
FROM [dbo].[LoadHistory] LH
WHERE ST.SystemDetailID = LH.SystemDetailID
ORDER BY LoadHistoryID DESC) LH
You can also use row_number
WITH LH
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY SystemDetailID
ORDER BY LoadHistoryID DESC) RN
FROM [dbo].[LoadHistory])
SELECT ST.[SystemDetailID],
ST.[SystemName],
LH.LatestLoadStatus
FROM [SystemTable] AS ST
LEFT JOIN LH
ON LH.SystemDetailID = ST.SystemDetailID
AND LH.RN = 1
SELECT ST.[SystemDetailID], ST.[SystemName], LH.LatestLoadStatus
FROM [SystemTable] AS ST
INNER JOIN [dbo].[LoadHistory] AS LH
ON ST.SystemDetailID = LH.SystemDetailID
AND LH.LoadHistoryID IN
(SELECT MAX(LoadHistoryID) as LoadHistoryID
FROM [dbo].[LoadHistory]
GROUP BY SystemDetailID )