Select records with fewer than 10 entries sql server - sql

i want only to display the The ID which have record less than 10 entries for each ID, an ID may have several values as you see in the data below. i want
i have tried this query but it selects also the record for ID 2
select ID, Name ,LastName ,PaymentDate,POSITION
From ( select ID, Name ,LastName ,PaymentDate ,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY PaymentDate DESC) AS POSITION
)
where Position < 10
any help please
ID Name LastName PaymentDate
1 John Abraham 2015-05-08
1 John Abraham 2014-05-08
1 John Abraham 2013-05-08
1 John Abraham 2012-05-08
1 John Abraham 2011-05-08
1 John Abraham 2010-05-08
------------------------------
2 Adam White 2015-05-08
2 Adam White 2014-05-08
2 Adam White 2013-05-08
2 Adam White 2012-05-08
2 Adam White 2011-05-08
2 Adam White 2010-05-08
2 Adam White 2009-05-08
2 Adam White 2008-05-08
2 Adam White 2007-05-08
2 Adam White 2006-05-08
2 Adam White 2005-05-08
2 Adam White 20004-05-08

SELECT ID, COUNT(ID)
FROM sometable
GROUP BY ID
HAVING COUNT(ID) < 10

You want count(*), not row_number():
select ID, Name, LastName, PaymentDate
from (select ID, Name, LastName, PaymentDate,
count(*) over (partition by ID) as cnt
from . . .
) t
where cnt < 10;
This displays the rows (which your question suggests is what you want). If you want only the ids, then aggregation is better:
select id
from t
group by id
having count(*) < 10;

Please try:
Select ID, Name, LastName, PaymentDate
From MyTable
Where ID in (Select ID From MyTable Group By ID Having Count(*) < 10);

Related

SQL Query: New columns for data with some matching criteria

I'm working with a query that pulls data from a table and arranges it in a manner similar to below:
Query1
BldID UnitID Res1
1 201 John Smith
1 201 Jane Doe
1 202 Daniel Jones
1 202 Mark Garcia
2 201 Maria Lee
2 201 Paul Williams
2 201 Mike Jones
I'd like to modify the query output in SQL/Design so that each resident that shares a building / unit shows as a new column on the same row as shown below:
BldID UnitID Res1 Res2 Res3
1 201 John Smith Jane Doe
1 202 Daniel Jones Mark Garcia
2 201 Maria Lee Paul Williams Mike Jones
I apologize if this is crude/not enough information but any help would be greatly appreciated.
You can try using conditional aggregation
with cte as
(
select *, row_number() over(partition by BldID,UnitID order by Res1) as rn
from tablename
)
select BldID,UnitID,
max(case when rn=1 then Res1 end) as Res1,
max(case when rn=2 then Res1 end) as Res2,
max(case when rn=3 then Res1 end) as Res3
from cte
group by BldID,UnitID
So, drawing from a few different sources, this might work, try pasting this intoa query editor, and see if it'll run.
TRANSFORM MAX(Res1)
SELECT BldID, UnitID
, (
SELECT COUNT(T1.Marks)
FROM tableName AS T1
WHERE
T1.BldgID = T2.BldgID AND
T1.UnitID = T2.UnitID AND
T1.Res1 >= T2.Res1
) AS Rank, Res1
FROM tableName t2
GROUP BY BldID, UnitID
PIVOT Rank;
2 years late, but maybe I can add something, in Access we are surgeons operating with kitchen knifes, things must be done in the Access Way...
I tested it having this table UnitStudentBlock
BldID
UnitID
Res1
1
201
John Smith
1
201
Jane Doe
1
202
Daniel Jones
1
202
Mark Garcia
2
201
Maria Lee
2
201
Paul Williams
2
201
Mike Jones
2
201
Julian Gomes
As Access doesn't have row_number, first I created a table with an auto increment field so that we can have something like a row number:
CREATE TABLE TableWithId
(
Id COUNTER,
BldID INT,
UnitID INT,
Res1 VARCHAR(100),
ResNumber VARCHAR(100)
)
Then I inserted all the data from the initial table into this newly created table:
INSERT INTO TableWithId (BldID, UnitID, Res1)
SELECT *
FROM UnitStudentBlock
ORDER BY BldID,
UnitID
Then I updated everything using DCOUNT to have a row_number partitioned:
UPDATE TableWithId
SET ResNumber = 'Res' + Cstr(DCOUNT("*", "TableWithId", "ID >=" & [ID]
& " AND UnitId = " & [UnitId]
& " AND BldId = " & [BldId]))
And finally we can run the query that returns the data:
TRANSFORM MAX(Res1)
SELECT BldID, UnitID
FROM TableWithId
GROUP BY BldID, UnitID
PIVOT ResNumber

How to query: "for which do these values apply"?

I'm trying to match and align data, or resaid, count occurrences and then list for which values those occurrences occur.
Or, in a question: "How many times does each ID value occur, and for what names?"
For example, with this input
Name ID
-------------
jim 123
jim 234
jim 345
john 123
john 345
jane 234
jane 345
jan 45678
I want the output to be:
count ID name name name
------------------------------------
3 345 jim john jane
2 123 jim john
2 234 jim jane
1 45678 jan
Or similarly, the input could be (noticing that the ID values are not aligned),
jim john jane jan
----------------------------
123 345 234 45678
234 123 345
345
but that seems to complicate things.
As close as I am to the desired results is in SQL, as
for ID, count(ID)
from table
group by (ID)
order by count desc
which outputs
ID count
------------
345 3
123 2
234 2
45678 1
I'll appreciate help.
You seem to want a pivot. In SQL, you have to specify the number of columns in advance (unless you construct the query as a string).
But the idea is:
select ID, count(*) as cnt,
max(case when seqnum = 1 then name end) as name_1,
max(case when seqnum = 2 then name end) as name_2,
max(case when seqnum = 3 then name end) as name_3
from (select t.*,
row_number() over (partition by id order by id) as seqnum -- arbitrary ordering
from table t
) t
group by ID
order by count desc;
If you have an unknown number of columns, you can aggregate the values into an array:
select ID, count(*) as cnt,
array_agg(name order by name) as names
from table t
group by ID
order by count desc
the query would look similar to this if that's what you're looking for.
SELECT
name,
id,
COUNT(id) as count
FROM
dataSet
WHERE
dataSet.name = 'input'
AND dataSet.id = 'input'
GROUP BY
name,
id

SQL: Adding new column to show count of ID by date

I am hoping someone can help me with my query.
I have a table with the columns, 'Date', 'ID_Num and 'Name'. What I want to do is add a column at the end to show the total amount of times each ID_Num is within the data but based on the date. So although 'ID_Num' 1001 shows 4 times in total, it is twice on the 20/04/2018 and once on both the 21/04/2018 and 22/04/2018.
EDIT: I should have stipulated that I will be pulling several other columns with information, which I cant use a group by on everything.
Date ID_Num Name Count
20/04/2018 1001 John 2
20/04/2018 1001 John 2
20/04/2018 1002 Paul 2
20/04/2018 1002 Paul 2
20/04/2018 1003 David 2
20/04/2018 1003 David 2
20/04/2018 1004 Stephen 1
21/04/2018 1001 John 1
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1004 Stephen 1
22/04/2018 1001 John 1
22/04/2018 1002 Paul 1
22/04/2018 1003 David 1
22/04/2018 1004 Stephen 1
Thanks
Unless I'm missing something here, a simple group by and count should do it:
SELECT Date, ID_Num, Name, Count(*)
FROM TableName
GROUP BY Date, ID_Num, Name
(That is, assuming there can only be one Name for each ID_Num)
Update
Assuming your rdbms supports it, you can use count with an over clause:
SELECT Date, ID_Num, Name, Count(*) OVER(PARTITION BY Date, Id_Num)
FROM TableName
If not, you can use a sub query:
SELECT Date,
ID_Num,
Name,
(SELECT Count(*)
FROM TableName As t1
WHERE t1.Date = t0.Date
AND t1.ID_NUM = t0.ID_NUM)
FROM TableName As t0
Try this:
SELECT
Date,
Id_num,
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num
If you want name as well:
SELECT
Date,
Id_num,
Name
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num,
Name
You can use a normal select query and then add a sub query to do a group and show the total. Simple example below
SELECT Date, ID_Num, Name,
(SELECT Count(ID_Num) FROM TableName AS CHILD WHERE CHILD.Id_Num = Parent.Id_Num) AS Total
FROM TableName AS Parent

Display the latest modified record for each employee

emp table as like this
id Name Date Modified
1 Ram 2017-01-05
2 Kishore 2017-02-04
3 John 2017-04-22
1 Ram K 2017-04-25
1 Ram Kumar 2017-05-01
2 Kishore Babu 2017-05-05
3 John B 2017-06-01
Assuming you're using a reasonable rdbms that supports window functions, row_number should do the trick:
SELECT id, name, date_modified
FROM (SELECT id, name, date_modified,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY date_modified DESC) rn
FROM emp) t
WHERE rn = 1

Order pairs/triplets of rows given the sum of a column

I'd like to order pairs (or group of 3,4 etc.) of rows given the SUM of a certain value.
The rows are consecutive based on the concatenation of Name+Surname+Age
To better understand given the following table:
ID Name Surname Age Salary
------------------------------
1 John Smith 30 2
2 John Smith 30 10
3 Rick James 22 300
4 Rick James 22 1000
5 Rick James 22 5
6 Mike Brown 50 200
7 Mike Brown 50 20
I'd like to have a final table that should be ordered DESC by the sum of Salary of each Name+Surname+Age and keeping the rows with same Name+Surname+Age next to each others despite the ID column is different. This would be the expected result:
ID Name Surname Age Salary
------------------------------
3 Rick James 22 300
4 Rick James 22 1000
5 Rick James 22 5
6 Mike Brown 50 200
7 Mike Brown 50 20
1 John Smith 30 2
2 John Smith 30 10
As you can see the rows with Name+Surname+Age = "Rick Jams 22" are on the top since their total sum would be 1305, followed by "Mike Brown 50" (sum = 220) and "John Smith 30" (sum = 12).
Additionally, the number of rows has to be the same in the resulting table.
How can I do that using Oracle SQL?
Thanks for any help
SELECT t.*,
COALESCE(SUM(salary) OVER (PARTITION BY name, surname, age), 0) ss
FROM mytable t
ORDER BY
ss DESC
Try this:
SELECT ID, Name, Surname, Age, Salary
FROM (
SELECT ID, Name, Surname, Age, Salary,
SUM(Salary) OVER (PARTITION BY Name, Surname, Age) AS sum_of_sal
FROM mytable) t
ORDER BY sum_of_sal DESC, ID
The query uses the window version of SUM in order to calculate the sum of salaries per Name, Surname, Age partition. We can use this field in an outer query to do the sorting.
or try this
SELECT ID, Name, Surname, Age, Salary
FROM mytable
ORDER BY SUM(Salary) OVER (PARTITION BY Name, Surname, Age) DESC, ID