Subquery with Sum of top X rows - sql

I am trying to get the top 5 results for each person from a table. I am able to get the top result for them however I want the sum of the top 5.
Select Distinct
r.LastName,
r.FirstName ,
r.Class,
r.BibNum,
(Select top 1 r2.points from Results r2 where r2.season=r.Season and r2.Mountain=r.Mountain and r2.Bibnum=r.bibnum Order By r2.Points Desc) as Points
from Results as r Where Season='2015' and Mountain='Ski Resort'
Order By Class, Points Desc
Columns:
[Id] [int] IDENTITY(1,1) NOT NULL,
[RaceNum] [int] NOT NULL,
[BibNum] [int] NOT NULL,
[FirstName] [nvarchar](max) NULL,
[LastName] [nvarchar](max) NULL,
[Sex] [nvarchar](max) NULL,
[Class] [nvarchar](max) NULL,
[Team] [nvarchar](max) NULL,
[FirstRun] [nvarchar](max) NULL,
[SecondRun] [nvarchar](max) NULL,
[Best] [nvarchar](max) NULL,
[Points] [int] NOT NULL,
[Season] [int] NOT NULL,
[Mountain] [nvarchar](max) NULL

You could use row_number() to get the top five rows, and then group by the other fields:
SELECT LastName,
FirstName,
Class,
BibNum,
SUM(points)
FROM (SELECT LastName,
FirstName,
Class,
BibNum,
points,
ROW_NUMBER() OVER (PARTITION BY LastName,
FirstName,
Class,
BibNum
ORDER BY points DESC) AS rn
FROM results
WHERE Season='2015' and Mountain='Ski Resort'
) t
WHERE rn <= 5
GROUP BY LastName, FirstName, Class, BibNum

Related

SQL select command consume 100% CPU while executing

In my query I'm Selecting row by row closing balance. It's consume 100% CPU while executing is sql server 2014.
Here is my query:
;WITH summary(id,reference_id,entry_date,particular,remarks,debit,credit,balance)AS(
SELECT
id,
reference_id,
entry_date,
particular,
remarks,
debit,
credit,
(credit-debit)+(SELECT ISNULL(SUM(l.credit-l.debit) ,0) FROM member_transaction l WHERE l.entry_date<a.entry_date AND l.member_id=#mId AND is_succeed=1 AND isnull(l.reference_id,0) NOT IN(SELECT user_reference_id FROM recharge_request WHERE status='Failure'))AS balance
FROM member_transaction a
WHERE member_id=#mId AND is_succeed=1
AND isnull(reference_id,0) NOT IN(SELECT user_reference_id FROM recharge_request WHERE status='Failure')),
openingbalance(
id,
reference_id,
entry_date,
particular,
remarks,
debit,
credit,
balance
)AS(SELECT TOP 1 0,'','','OPENING BALANCE','',0,0,balance FROM summary WHERE entry_date<'2017/03/10' ORDER BY entry_date DESC
)SELECT * FROM openingbalance UNION SELECT * FROM summary ORDER BY entry_date DESC
Is there any other way to calculate row by row closing balance on every transaction? Please help me to solve this problem.
HERE is table structure:
CREATE TABLE [member_transaction](
[id] [int] IDENTITY(1,1) NOT NULL,
[member_id] [int] NULL,
[t_type] [varchar](50) NULL,
[debit] [decimal](12, 2) NOT NULL,
[credit] [decimal](12, 2) NOT NULL,
[particular] [varchar](100) NULL,
[remarks] [varchar](150) NULL,
[reference_id] [varchar](50) NULL,
[entry_date] [datetime] NOT NULL,
[is_succeed] [bit] NOT NULL
)
CREATE TABLE [recharge_request](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[mobile_no] [varchar](50) NULL,
[amount] [decimal](12, 0) NULL,
[user_reference_id] [varchar](50) NULL,
[uid] [int] NULL,
[rdate] [datetime] NOT NULL,
[status] [varchar](50) NOT NULL
)
Assuming you're in SQL Server 2012+, you should try something like this:
SELECT
id,
reference_id,
entry_date,
particular,
remarks,
debit,
credit,
sum(isnull(credit,0)-isnull(debit,0)) over (order by entry_date asc) AS balance
FROM
member_transaction a
WHERE
member_id=#mId AND
is_succeed=1 AND
not exist (select 1 FROM recharge_request r WHERE r.user_reference_id = a.reference_id and r.status='Failure')
If you want to fetch more than one member, then you should have partition by in the over part of the sum.

How do I aggregate 3 columns that are different with MIN(DATE)?

I'm facing a simple problem here that I can't solve, I have this query:
SELECT
MIN(TEA_InicioTarefa),
PFJ_Id_Analista,
ATC_Id,
SRV_Id
FROM
dbo.TarefaEtapaAreaTecnica
INNER JOIN Tarefa t ON t.TRF_Id = TarefaEtapaAreaTecnica.TRF_Id
WHERE SRV_Id = 88
GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista
ORDER BY ATC_Id ASC
It returns me this:
I was able to group it a little with GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista that gave me these 8 records, but as you can see some PFJ_Id_Analista are different.
What I want is to select only the early date of each SRV_Id and ATC_Id, the PFJ_Id_Analista don't need to grup, if I remove PFJ_Id_Analista from the grouping the query works, but I need the column.
For eg.: between row number 2 and 3 I want only the early date, so it will be row 2. The same goes for rows 5 to 8, I want only row 6.
DDL for TarefaEtapaAreaTecnica (important key: TRF_Id)
CREATE TABLE [dbo].[TarefaEtapaAreaTecnica](
[TEA_Id] [int] IDENTITY(1,1) NOT NULL,
**[TRF_Id] [int] NOT NULL,**
[ETS_Id] [int] NOT NULL,
[ATC_Id] [int] NOT NULL,
[TEA_Revisao] [int] NOT NULL,
[PFJ_Id_Projetista] [int] NULL,
[TEA_DoctosQtd] [int] NULL,
[TEA_InicioTarefa] [datetime2](7) NULL,
[PFJ_Id_Analista] [int] NULL,
[TEA_FimTarefa] [datetime2](7) NULL,
[TEA_HorasQtd] [numeric](18, 1) NULL,
[TEA_NcfQtd] [int] NULL,
[PAT_Id] [int] NULL
DDL for Tarefa (important keys TRF_Id and SRV_Id (which I need it)):
CREATE TABLE [dbo].[Tarefa](
**[TRF_Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,**
**[SRV_Id] [int] NOT NULL,**
[TRT_Id] [int] NOT NULL,
[TRF_Descr] [varchar](255) NULL,
[TRF_Entrada] [datetime] NOT NULL,
[TRF_DoctosQtd] [int] NOT NULL,
[TRF_Devolucao] [datetime] NULL,
[TRF_NcfQtd] [int] NULL,
[TRF_EhDocInsuf] [bit] NULL,
[TRF_Observ] [varchar](255) NULL,
[TRF_AreasTrfQtd] [int] NULL,
[TRF_AreasTrfLiqQtd] [int] NULL
Thanks a lot.
EDIT:
CORRECT QUERY
Based on #Gordon Linoff post:
select t.TEA_InicioTarefa, t.PFJ_Id_Analista, t.ATC_Id, t.SRV_Id
from (select t.*,
row_number() over (partition by ATC_Id, SRV_Id
order by TEA_InicioTarefa) as seqnum, ta.SRV_Id
from dbo.TarefaEtapaAreaTecnica t
inner join dbo.Tarefa ta on t.TRF_Id = ta.TRF_Id
) t
where seqnum = 1 AND t.SRV_Id = 88
Just use window functions:
select t.*
from (select t.*,
row_number() over (partition by ATC_Id, SRV_Id
order by ini) as seqnum
from dbo.TarefaEtapaAreaTecnica t
) t
where seqnum = 1;
This is really an example of filtering, not aggregation. The problem is getting the right value to filter on.
Then get the grouping first and then do a JOIN with it like
SELECT
x.Min_TEA_InicioTarefa,
t.PFJ_Id_Analista,
t.ATC_Id,
t.SRV_Id
FROM
dbo.TarefaEtapaAreaTecnica t
INNER JOIN Tarefa ta ON ta.TRF_Id = t.TRF_Id
INNER JOIN (
select SRV_Id, MIN(TEA_InicioTarefa) as Min_TEA_InicioTarefa
from dbo.TarefaEtapaAreaTecnica
GROUP BY SRV_Id
) x ON t.SRV_Id = x.SRV_Id
WHERE t.SRV_Id = 88
ORDER BY t.ATC_Id ASC;

SQL fastest 'GROUP BY' script

Is there any difference in how I edit the GROUP BY command?
my code:
SELECT Number, Id
FROM Table
WHERE(....)
GROUP BY Id, Number
is it faster if i edit it like this:
SELECT Number, Id
FROM Table
WHERE(....)
GROUP BY Number , Id
it's better to use DISTINCT if you don't want to aggregate data. Otherwise, there is no difference between the two queries you provided, it'll produce the same query plan
This examples are equal.
DDL:
CREATE TABLE dbo.[WorkOut]
(
[WorkOutID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[TimeSheetDate] [datetime] NOT NULL,
[DateOut] [datetime] NOT NULL,
[EmployeeID] [int] NOT NULL,
[IsMainWorkPlace] [bit] NOT NULL,
[DepartmentUID] [uniqueidentifier] NOT NULL,
[WorkPlaceUID] [uniqueidentifier] NULL,
[TeamUID] [uniqueidentifier] NULL,
[WorkShiftCD] [nvarchar](10) NULL,
[WorkHours] [real] NULL,
[AbsenceCode] [varchar](25) NULL,
[PaymentType] [char](2) NULL,
[CategoryID] [int] NULL
)
Query:
SELECT wo.WorkOutID, wo.TimeSheetDate
FROM dbo.WorkOut wo
GROUP BY wo.WorkOutID, wo.TimeSheetDate
SELECT DISTINCT wo.WorkOutID, wo.TimeSheetDate
FROM dbo.WorkOut wo
SELECT wo.DateOut, wo.EmployeeID
FROM dbo.WorkOut wo
GROUP BY wo.DateOut, wo.EmployeeID
SELECT DISTINCT wo.DateOut, wo.EmployeeID
FROM dbo.WorkOut wo
Execution plan:

Return rows which have same data in three columns

I have a table with the following schema
CREATE TABLE [dbo].[personas](
[id_persona] [int] IDENTITY(1,1) NOT NULL,
[nombres] [nvarchar](50) NOT NULL,
[apellido_paterno] [nvarchar](50) NULL,
[apellido_materno] [nvarchar](50) NULL,
[fecha_nacimiento] [date] NOT NULL,
[sexo] [varchar](1) NOT NULL,
[estado_civil] [nvarchar](50) NOT NULL,
[calle] [nvarchar](200) NULL,
[colonia] [nvarchar](100) NULL,
[codigo_postal] [char](5) NOT NULL,
[telefonos] [varchar](50) NULL,
[celular] [varchar](25) NULL,
[email] [varchar](50) NULL,
)
How do I make a query in SQL Server to return rows where nombre, apellido_paterno and apellido_materno are repeated? I mean two or more rows have the same data in these columns.
I suppose I'm looking something opposite to DISTINCT clause
You would want...
SELECT nombre, apellido_paterno, apellido_materno
FROM dbo.personas
GROUP BY nombre, apellido_paterno, apellido_materno
HAVING COUNT(*) > 1
If you want to look at the actual rows, then use that as an inner query and join onto it. So, something like
SELECT *
FROM personas pOuter INNER JOIN
(SELECT nombre, apellido_paterno, apellido_materno
FROM dbo.personas
GROUP BY nombre, apellido_paterno, apellido_materno
HAVING COUNT(*) > 1) pInner
ON pInner.nombre = pOuter.nombre
AND pInner.apellido_paterno = pOuter.apellido_paterno
AND pInner.apellido_materno = pOuter.apellido_materno
;WITH x AS
(
SELECT id_personas, rn = ROW_NUMBER() OVER
(
PARTITION BY nombre, apellido_paterno, apellido_materno
ORDER BY id_personas
)
FROM dbo.personas
)
SELECT <col list>
FROM dbo.personas AS p
WHERE EXISTS
(
SELECT 1 FROM x
WHERE x.id_personas = p.id_personas
AND x.rn > 1
);

Select rows not in another table, SQL Server query

Subject table
CREATE TABLE [dbo].[BS_Subject](
[SubjectID] [bigint] IDENTITY(1,1) NOT NULL,
[DepartmentID] [bigint] NOT NULL,
[SubjectName] [varchar](50) NOT NULL,
[SubjectDescription] [varchar](100) NULL,
[SubjectShortCode] [varchar](10) NOT NULL,
CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED
(
[SubjectID] ASC
)
SubjectToClass table
CREATE TABLE [dbo].[BS_SubjectToClass](
[SubjectToClassID] [bigint] IDENTITY(1,1) NOT NULL,
[SubjectID] [bigint] NOT NULL,
[ClassID] [bigint] NOT NULL,
CONSTRAINT [PK_BS_SubjectToClass] PRIMARY KEY CLUSTERED
(
[SubjectToClassID] ASC
)
I need list all the rows in the Subject table where subjectid is not in SubjectToClass table of a specified class.
I have this but unable to go any further
select Distinct(BS_Subject.SubjectID) DepartmentID,
SubjectName, SubjectDescription, SubjectShortCode
from dbo.BS_Subject
where BS_Subject.SubjectID <> (
SELECT Distinct(BS_Subject.SubjectID)
FROM dbo.BS_Subject, dbo.BS_SubjectToClass
Where BS_Subject.SubjectID = BS_SubjectToClass.SubjectID
And BS_SubjectToClass.ClassID = 2)
SELECT SubjectID, DepartmentID, SubjectName, SubjectDescription, SubjectShortCode
FROM BS_Subject
WHERE NOT EXISTS
(SELECT SubjectToClassID FROM BS_SubjectToClass WHERE
BS_Subject.SubjectID = BS_SubjectToClass.SubjectID
AND BS_SubjectToClass.ClassID =2)
You need to use the NOT IN operator - not the <> (that's VB or something....)
SELECT
DISTINCT(BS_Subject.SubjectID) DepartmentID,
SubjectName, SubjectDescription, SubjectShortCode
FROM dbo.BS_Subject
WHERE
BS_Subject.SubjectID NOT IN
(SELECT DISTINCT(BS_Subject.SubjectID)
FROM dbo.BS_Subject, dbo.BS_SubjectToClass
WHERE BS_Subject.SubjectID = BS_SubjectToClass.SubjectID
AND BS_SubjectToClass.ClassID = 2)