I have a table having data like
pin id name
3 33 jjj
2 22 bbb
1 111 aaaa
1 112 aa
1 113 aaa
4 44 kkk
I want to print rows of the table where if count(*) group by pin =1 (i.e single entry in table ) print the row
if count(*) group by pin >2 then print first two rows
so my out put should be
pin id name
3 33 jjj
2 22 bbb
1 111 aaaa
1 112 aa
4 44 kkk
Use row_number() OVER(partion by pin order by id) as rownum function . Where rownum <3
. As #Clockwork-Muse said, you need to define an order becase you need to say what do you want to see if there are more than 2 rows for a particular pin.
This will generate you desired output.
Related
i have the following codes which displays the following result
select distinct
srcaccountid,
srccharid,
srccharname,
action,
itemname,
sum(itemcount) over (partition by srccharname, itemname)
as total_count,
sum(price) over(partition by srccharname, itemname)
as total_price
from
itemlog
where
action = 6
and logtime >='2023-02-13'
order by
total_count desc,
srcaccountid
the result is as follows
srcaccountid srccharid srccharname action itemname total_count total_price
1 21 abc 6 dog 2222 231
2 22 sdd 6 cat 1234 122
1 21 abc 6 cat 324 77
1 21 abc 6 mouse 122 32
2 22 sdd 6 mouse 12 3
i will like the result to show as follow
srcaccountid srccharid srccharname action itemname total_count
total_price
1 21 abc 6 dog 2222 231
1 21 abc 6 cat 324 77
1 21 abc 6 mouse 122 32
2 22 sdd 6 cat 1234 122
2 22 sdd 6 mouse 12 3
i cant seem to be able to show the highest sales amount while grouping the ids together and not splitting them up
Change the order by. Put the srcaccountid first.
order by
srcaccountid,
total_count desc
I need to select the records in batch wise, like in below example we have 20 records. if I give batch of size of 10 there would be two loops. the problem here is if I do top 10 then 555 value will be split as its position is 10 and 11. hence 555 should also include in that top first batch. how I can achieve this? this is just example, I have 900 million records to process and my batch will be 2 million in real scenario.
ID
-------
111
111
111
222
222
333
333
444
444
555
555
666
666
777
777
888
888
You can use top with ties - this might return more records then stated but will not break similar ids to different batches:
Create and populate sample table (Please save us this step in your future questions):
DECLARE #T AS TABLE
(ID int)
INSERT INTO #T VALUES
(111),(111),(111),
(222),(222),
(333),(333),
(444),(444),
(555),(555),
(666),(666),
(777),(777),
(888),(888)
The select statement:
SELECT TOP 10 WITH TIES ID
FROM #T
ORDER BY ID
Results:
row ID
1 111
2 111
3 111
4 222
5 222
6 333
7 333
8 444
9 444
10 555
11 555
While selecting the records, you can group them by id prior to limiting their number.
Consider the table Property.
KeyIdNum|Property|IdNum
1 12 1234
1 12 1234
1 44 1234
1 12 1234
1 56 1234
2 12 4567
3 12 6789
3 56 6789
3 12 6789
4 44 3434
5 12 4444
6 44 9999
6 44 9999
It contains property num associated with each id num.But it contains duplicates.
I applied distinct to avoid duplicates.
select distinct KeyIdNum,Property,IdNum from Property.
So i got the result as :
KeyIdNum |Property |IdNum
1 12 1234
1 44 1234
1 56 1234
2 12 4567
3 12 6789
3 56 6789
4 44 3434
5 12 4444
6 44 9999
But now I want to `select( after applying distinct) ,the KeyIdNum (or IdNum) which are coming more than one time in the distinct result set shown above.
Please help me on this.I am not able to find a way to get the count of a column in the distinct result set using a single query.
Below query will result of KeyidNum , its number of row count.
select KeyIdNum,count(KeyIdNum)
From (
select distinct KeyIdNum,Property,IdNum from Property )
group by KeyIdNum
select KeyIdNum,count(KeyIdNum) as count
From (
select distinct KeyIdNum,Property,IdNum from Table19 )A
group by KeyIdNum
output
KeyIdNum count
1 3
2 1
3 2
4 1
5 1
6 1
This answer uses t-sql:
SELECT x
FROM ( SELECT * ,
rn = rownumber() OVER ( PARTITION BY keyidnum, idnum
ORDER BY keyidnum, idnum )
FROM tblProperty
) x
WHERE rn > 1
I'm attempting to create group_ids based on a set of item_ids. The only indication that the item_ids are part of a single group is the fact that item_ids are sequential. For example, based on the first two columns below, the output I want is the third:
item item_id group_id
ABC 282 2
ABC 283 2
ABC 284 2
ABC 285 2
ABC 051 3
ABC 052 3
ABC 189 4
ABC 231 5
ABC 232 5
ABC 233 5
ABC 234 5
ABC 247 6
ABC 248 6
ABC 249 6
ABC 250 6
ABC 091 7
ABC 092 7
The group_id doesn't necessarily have to be sequential itself, it only has to be unique. I attempted this with the following code:
create sequence seq
start with 1
minvalue 1
increment by 1
cache 20;
select seq.nextval from dual; --to initialize the sequence
select
item,
item_id,
case when diff = 1 then seq.currval else seq.nextval end group_id
from
(
select
item,
item_id,
(id - lag(id, 1, 0) over (order by 1) diff
from
(
select
item,
item_id
from
table
)
);
But get the following output:
item item_id group_id
ABC 282 2
ABC 283 3
ABC 284 4
ABC 285 5
ABC 051 6
ABC 052 7
ABC 189 8
ABC 231 9
ABC 232 10
ABC 233 11
ABC 234 12
ABC 247 13
ABC 248 14
ABC 249 15
ABC 250 16
ABC 091 17
ABC 092 18
When looking for the cause of the problem, I found an excellent explanation by user ShannonSeverance that details why my solution won't work. However, it didn't provide any suggestions on how to move forward.
Does anyone have any ideas?
You have a problem, because SQL tables are inherently unordered. The following "should" logically work, although it won't in practice:
select ii.*, (item_id - rownum) as grp_id
from item_ids ii;
A sequence of item_ids in order minus the row number is constant. You can use that for a group, at least for a given item. To handle multiple items, concatenate the values together:
select ii.*, item||'-'||(item_id - rownum) as grp_id
from item_ids ii;
To really make this work, you need to add an order by -- this guarantees the ordering of the results from the select. This might work, assuming that there are "holes" between the groups:
select ii.*, item||'-'||(item_id - rownum) as grp_id
from item_ids ii
order by item, item_id;
Otherwise, you need some other column to determine the proper ordering for the items.
I have a table with an ID and multiple informative columns. Sometimes however, I can have multiple data for an ID, so I added a column called "Sequence". Here is a shortened example:
ID Sequence Name Tel Date Amount
124 1 Bob 873-4356 2001-02-03 10
124 2 Bob 873-4356 2002-03-12 7
124 3 Bob 873-4351 2006-07-08 24
125 1 John 983-4568 2007-02-01 3
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
So, I would like to obtain only these lines:
124 3 Bob 873-4351 2006-07-08 24
125 2 John 983-4568 2008-02-08 13
126 1 Eric 345-9845 2010-01-01 18
Anyone could give me a hand on how I could build a SQL query to do this ?
Thanks !
You can calculate the maximum sequence using group by. Then you can use join to get only the maximum in the original data.
Assuming your table is called t:
select t.*
from t join
(select id, MAX(sequence) as maxs
from t
group by id
) tmax
on t.id = tmax.id and
t.sequence = tmax.maxs