I need to write a SQL query which will get me those rows from the table which have the max value of files.
The database table is as follows:
> ID status dept files
>
> > 1 1 23 1256637314
> >
> > 1 1 39 1256642968
> >
> > 2 0 85 1256551419
> >
> > 2 1 90 1256642968
> >
> > 2 1 93 1256810937
> >
> > 3 0 20 1256642968
> >
> > 5 1 342 1256810937
Now from this table i want to get those rows which have the maximum files grouping by ID:
> ID status dept files
>
> 1 1 39 1256642968
>
> 2 1 93 1256810937
>
> 3 0 20 1256642968
>
> 5 1 342 1256810937
Any suggestions??
Thanks.
i tried this but this is not right
Select ID, Status, dept,files
from SLAStat
where files in (Select Max(files) from SLAStat group by ID)
2 1 90 1256642968
1 1 39 1256642968
3 0 20 1256642968
5 1 342 1256810937
2 1 93 1256810937
Replace #t1 by your table:
With idT as (
select ID
from #t1
group by id
)
select applyT.*
from idT p
CROSS APPLY (
select top 1 * from #t1 where ID=p.ID order by files desc
) as applyT
SELECT DISTINCT a.ID, a.Status, a.Dept, a.Files
FROM table a
INNER JOIN (
SELECT ID, MAX(files) AS Files
FROM table
GROUP BY ID) b ON a.ID = b.ID AND a.Files = b.Files
SELECT MAX(files) as max_files, id, status, dept
FROM table
GROUP BY id
I may be over-simplifying the problem, but:
select top 5 * from SLAStat order by files desc;
Related
table ta having four columns ( SQL server and D column is date)
A | B | C|D
1 |11| 0|10-MAY-2019
1 |12| 0|10-MAY-2019
1 |13| 0|null
2 |33| 5|null
2 |34| 10|null
2 |35| 78|null
5 |45| 0|10-MAY-2019
5 |49| 0|10-MAY-2019
5 |51| 0|10-MAY-2019
8 |10| 0|1-MAY-2018
8 |14| 0|1-MAY-2018
8 |34| 0|1-MAY-2018
I am looking the SQL query to fetch the distinct A value which is having C value ZERO for all the B (ie. SUM(ABS(C))=0) and all D value for that will not be null and should be > GETDATE() - 90 (i.e any day between current date and 90 days)
From above table I would only get the value of A as '5'
Try this-
SELECT * FROM
(
SELECT A
FROM your_table
WHERE D > CAST(DATEADD(DD,-90,GETDATE()) AS DATE)
GROUP BY A
HAVING COUNT(A) = SUM(CASE WHEN C= 0 THEN 1 ELSE 0 END)
)A
WHERE NOT EXISTS
(
SELECT 1 FROM your_table B WHERE A.A = B.A
AND D IS NULL
)
You can use aggregation. I think this is the logic you describe:
select a
from t
where d > dateadd(day, -90, getdate()) or d is null
group by a
having max(c) = 0 and
count(*) = count(d); -- no NULL d values
I'm trying to get counts of how many jobs were done, regardless of personnel working on them. What I need to do is filter out any duplicates, the catch is that the entire row isn't duplicate so DISTINCT won't work here. I want to filter out if there is any duplication based on JobCode, JobType TaskTime and day of week. So my table looks like the following:
JobCode JobType TaskTime EmployeeID M Tu W Th F Sa Su
==================================================================
1800 1 06:49 101 1 1 1 1 1 0 0
1800 1 06:49 102 1 0 0 0 0 0 0
1800 1 07:04 101 1 1 1 1 1 0 0
1800 1 07:26 101 1 1 1 1 1 0 0
1800 1 07:49 101 1 1 1 1 1 0 0
1800 2 15:55 101 1 1 1 1 1 0 0
1800 1 16:20 101 1 1 1 1 1 0 0
1800 1 16:50 101 1 1 1 1 1 0 0
1800 2 16:55 101 1 1 1 1 1 0 0
My SQL Query is like this
SELECT t1.JobCode, t1.JobType,
t1.M, t1.Tu, t1.W, t1.Th, t1.F, t1.Sa, t1.Su,
SUM(t1.M + t1.Tu + t1.W + t1.Th + t1.F + t1.Sa + t1.Su) as Totals
FROM Table1 AS t1
JOIN Table1 AS t1_overlap ON
t1_overlap.EmployeeID = t1.EmployeeID AND
t1_overlap.JobType = t1.JobType AND
t1_overlap.TaskTime = t1.TaskTime
AND
(
(t1.M = 1 AND t1_overlap.M = t1.M) OR
(t1.Tu = 1 AND t1_overlap.Tu = t1.Tu) OR
(t1.W = 1 AND t1_overlap.W = t1.W) OR
(t1.Th = 1 AND t1_overlap.Th = t1.Th) OR
(t1.F = 1 AND t1_overlap.F = t1.F) OR
(t1.Sa = 1 AND t1_overlap.Sa = t1.Sa) OR
(t1.Su = 1 AND t1_overlap.Su = t1.Su)
)
GROUP BY t1.JobCode, t1.JobType, t1.M, t1.Tu, t1.W, t1.Th, t1.F, t1.Sa, t1.Su
The data returned is like this
JobCode JobType M Tu W Th F Sa Su Totals
==================================================
1800 1 1 0 0 0 0 0 0 1
1800 1 1 1 1 1 1 0 0 30
1800 2 1 1 1 1 1 1 1 10
What I want to see is only unique values, so I don't want that first line that shows the job was worked on by employee 102 on only M because I'm already seeing that employee 101 worked on that same job on that same day and time. So what I want to see instead is the following:
JobCode JobType M Tu W Th F Sa Su Totals
==================================================
1800 1 1 1 1 1 1 0 0 30
1800 2 1 1 1 1 1 0 0 10
Really I don't need to see the days of the week, I'm just showing them here so I can see whats being returned. All I actually need to see for output is the JobCode, JobType and Totals like the following:
JobCode JobType Totals
======================
1800 1 30
1800 2 10
Help is greatly appreciated.
I think a quick subquery where you grab the max of each day, grouping by your key, then sum the results, would do the trick:
SELECT
jobcode,
jobtype,
sum(monday+tuesday+wednesday+thursday+friday+saturday+sunday) AS total
FROM
(
SELECT
jobcode,
jobtype,
tasktime,
max(m) as monday,
max(tu) as tuesday,
max(w) as wednesday,
max(th) as thursday,
max(f) as friday,
max(sa) as saturday,
max(su) as sunday
FROM Table1 T1
GROUP BY jobcode, jobtype, tasktime
) t2
GROUP BY jobcode, jobtype
There may be something more eloquent than that, but this should get the job done.
Try with the below query.
;With cte1
as
(SELECT ROW_NUMBER()OVER(PArtition by t1.JobCode,t1.JobType order by t1.JobCode,t1.JobType) RNO,t1.JobCode, t1.JobType,
SUM(t1.M + t1.Tu + t1.W + t1.Th + t1.F + t1.Sa + t1.Su) OVER(partition by t1.JobCode,t1.JobType ORDER BY t1.JobCode,t1.JobType ) as Totals
FROM Table1 AS t1
JOIN Table1 AS t1_overlap ON
t1_overlap.EmployeeID = t1.EmployeeID AND
t1_overlap.JobType = t1.JobType AND
t1_overlap.TaskTime = t1.TaskTime
AND
(
(t1.M = 1 AND t1_overlap.M = t1.M) OR
(t1.Tu = 1 AND t1_overlap.Tu = t1.Tu) OR
(t1.W = 1 AND t1_overlap.W = t1.W) OR
(t1.Th = 1 AND t1_overlap.Th = t1.Th) OR
(t1.F = 1 AND t1_overlap.F = t1.F) OR
(t1.Sa = 1 AND t1_overlap.Sa = t1.Sa) OR
(t1.Su = 1 AND t1_overlap.Su = t1.Su)
))
SELECT t1.JobCode, t1.JobType,Totals
FROM cte1
WHERE RNO=1
Basically, you can use the super-awesome ROW_NUMBER function and wrap the query so that you effectively 1) define a grouping, and 2) take ONLY the first row of each group. Look closely at the over (partition by ... order by ...) clause to understand how you can control the grouping and the "ranking" (which ones you want to make it through to the results).
select JobCode, JobType, Totals
from (
SELECT t1.JobCode, t1.JobType, SUM(t1.M + t1.Tu + t1.W + t1.Th + t1.F + t1.Sa + t1.Su) as Totals
,row_number() over (partition by t1.JobCode order by t1.JobType) as rseq
FROM Table1 AS t1
JOIN Table1 AS t1_overlap ON
t1_overlap.EmployeeID = t1.EmployeeID AND
t1_overlap.JobType = t1.JobType AND
t1_overlap.TaskTime = t1.TaskTime
AND
(
(t1.M = 1 AND t1_overlap.M = t1.M) OR
(t1.Tu = 1 AND t1_overlap.Tu = t1.Tu) OR
(t1.W = 1 AND t1_overlap.W = t1.W) OR
(t1.Th = 1 AND t1_overlap.Th = t1.Th) OR
(t1.F = 1 AND t1_overlap.F = t1.F) OR
(t1.Sa = 1 AND t1_overlap.Sa = t1.Sa) OR
(t1.Su = 1 AND t1_overlap.Su = t1.Su)
)
GROUP BY t1.JobCode, t1.JobType, t1.M, t1.Tu, t1.W, t1.Th, t1.F, t1.Sa, t1.Su
) x
where rseq = 1 --filter to keep only the "first" row (JobType) for each JobCode
Note that the comments about "how do you decide which one to keep" are valid, and this example assumes you want to see "one row per JobCode", and keep the "first JobType for that JobCode". This can be adjusted to fit, if you'll explain the logic you want to use a little more clearly.
I need a little help on a SQL query. I could not get the result that I wanted.
ID I10 H 10NS HNS CC NSCC
0 1 1 1 1 14 14
1 0 1 0 1 6 2
1 0 2 0 2 12 2
1 0 3 0 3 17 4
1 0 3 0 3 18 4
1 0 3 0 3 19 4
1 0 3 0 3 20 4
What I want to have is one from each ID with highest CC
For example,
ID I10 H 10NS HNS CC NSCC
0 1 1 1 1 14 14
1 0 3 0 3 20 4
I tried with this code:
SELECT a.ID, b.name, a.i10 as[i-10-index], a.h as[h-index], 10ns as[i-10-index based on non-self-citation], a.hns as [h-index based on non-self-citation],
max(a.[Citation Count]), (a.[Non-Self-Citation Count])
FROM tbl_lpNumerical as a
join tbl_lpAcademician as b
on a.ID= (b.ID-1)
GROUP BY a.ID, b.name, a.i10, a.h, a.10ns, a.hns,
a.[Non-Self-Citation Count]
order by a.ID desc
However, I could not get the desired results.
Thank you for your time.
You can simply get all the row where not exist another row with an higher CC
SELECT n.*
FROM tbl_lpNumerical n
WHERE NOT EXISTS ( SELECT 'b'
FROM tbl_lpNumerical n2
WHERE n2.ID = n.ID
AND n2.CC > n.CC
)
In SQL Server, you can use row_number() for this. Based on your sample data`, something like:
select sd.*
from (select sd.*, row_number() over (partition by id order by cc desc) as seqnum
from sampledata sd
) sd
where seqnum = 1;
I have no idea what your query has to do with the sample data. If it generates the data, then you can use a CTE:
with sampledata as (
<some query here>
)
select sd.*
from (select sd.*, row_number() over (partition by id order by cc desc) as seqnum
from sampledata sd
) sd
where seqnum = 1;
The following query will select a single row from each ID partition: the one with the highest CC value:
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CC DESC) AS rn
FROM mytable) t
WHERE t.rn = 1
If there can be multiple rows having the same CC max value and you want all of them selected, then you can replace ROW_NUMBER() with RANK().
I have the following data in a table I'll call TableA:
ID Status Date
5 0 1000
20 0 900
10 1 800
30 1 700
4 1 600
8 0 500
22 1 400
1 1 300
3 0 200
The records are sorted by Date descendingly. I want to get only those records where Status is equal to 1 BUT only up to the first record where the Status is no longer 1. So in the sample data, records with ID: 10,30,4 would be selected but but 22 and 1 would not be because ID 8 appears and separates the sets. Preferrably the SQL should run in Sqlite. The result for this sample data should return:
ID Status Date
10 1 800
30 1 700
4 1 600
EDIT
I replaced the ID values with random values and changed the date from TEXT to Integer.
I suggest
select * from tableA a1 where a1.status = 1 and not exists
(select 1 from tableA a2 where a2.status = 0 and a2.date > a1.date and a2.date <
(select max(date) from tableA a3 where a3.status = 1
)
)
Doubly nested subquery. Select rows where the status is 1 that have no rows before them with (status is 0 and that are after the earliest row where status is 1).
No idea how efficient this is.
Here you go:
SELECT *
FROM
TableA A
INNER JOIN (
SELECT *
FROM TableA S
WHERE S.Status = 1
ORDER BY S.Date DESC
LIMIT 1
) S ON A.Date <= S.Date
WHERE
A.Status = 1
AND A.Date > (
SELECT E.Date
FROM TableA E
WHERE
E.Status = 0
AND S.Date > E.Date
ORDER BY Date DESC
LIMIT 1
)
;
See a Live Demo at SQL Fiddle
This should be pretty efficient because of the LIMIT clauses. If there are many rows in the table it theoretically won't be scanning them all--but big disclaimer: I don't work with sqlite much at all.
this is not tested, but will give an idea.
It's for MSSQL and uses subqueries; I dont know if it works for sqlite.
select RowNumber() r, *
from (select * from TableA where status = 1), (select top 1 id from TableA where status = 1) diff
where id - r = diff - 1
I have a table AssignmentMaster in that I have following columns with data
AssignmentID PaidAmount RefundAmount UserID
1 20 0 1
2 10 5 1
3 30 7 2
4 25 0 3
5 35 15 3
6 10 3 1
7 5 0 3
8 10 0 3
Now I want to find out the TotalNumberofAssignment with respect to userID, i.e. result should be:
UserID TotalAssignment TotalAssignmentofRefundAmount TotalPaidAmount TotalRefundAmount
1 3 2 40 8
2 1 1 30 7
3 4 1 75 15
How I can get above given result in MSSQL.
your any help will help me lot.
SELECT
UserID,
COUNT(AssignmentID) AS TotalAssignment,
SUM(SIGN(RefundAmount)) AS TotalAssignmentofRefundAmount,
SUM(PaidAmount) AS TotalPaidAmount,
SUM(RefundAmount) AS TotalRefundAmount
FROM
MyTable
GROUP BY
UserID
Note:
SIGN(RefundAmount) works if RefundAmount is always >= 0.
If not, change to
SUM(CASE WHEN RefundAmount <> 0 THEN 1 ELSE 0 END) AS TotalAssignmentofRefundAmount
Select UserID,
count(1) as TotalAssignment,
sum( case when RefundAmount = 0 then 0 else 1 end) as TotalAssignmentofRefundAmount,
sum(PaidAmount) as TotalPaidAmount ,
sum(RefundAmount) as TotalRefundAmount
From AssignmentMaster
Group by UserID
To show how to do this using nested SQL:
Select UserTotals.UserID, UserTotals.TotalAssignment,
Refunds.TotalAssignmentofRefundAmount,
UserTotals.TotalPaidAmount, UserTotals.TotalRefundAmount
From (select UserID,
Count(AssignmentID) [TotalAssignment],
Sum(PaidAmount) [TotalPaidAmount],
sum(RefundAmount) [TotalRefundAmount]
From #AssignmentMaster
Group By UserID
) [UserTotals] Left Join
(Select UserID,
Count(AssignmentID) [TotalAssignmentofRefundAmount]
From #AssignmentMaster
Where RefundAmount > 0
Group By UserID
) [Refunds] On Refunds.UserID = UserTotals.UserID
select UserId, count (AssignmentID) as TotalAssignment,
sum(case when RefundAmount = 0 then 0 else 1 end) as TotalAssignmentofRefundAmount,
sum(PaidAmount) as TotalPaidAmound,
sum(RefundAmount) as TotalRefundAmount
from AssignmentMaster
group by UserID;