Hi i have a table in which records as follows,every item have some variants and their quantity. i want to fetch only those item's record in which at least 3 variants value exist. ( a items have some qty in 3 variants but b have quantity only 2 variants, so i need only those record who have values at least in 3 records)
a 80 2
a 85 3
a 90 4
b 85 2
b 90 1
c 80 34
c 85 45
c 90 56
c 95 67
d 80 5
d 85 3
d 90 124
d 95 23
d 100 98
e 95 4
f 80 3
f 85 232
f 90 2
f 95 3
f 100 34
Result should be:
a 80 2
a 85 3
a 90 4
c 80 34
c 85 45
c 90 56
c 95 67
d 80 5
d 85 3
d 90 124
d 95 23
d 100 98
f 80 3
f 85 232
f 90 2
f 95 3
f 100 34
You can try with left join/is not null:
select t1.*
from tbl t1
left join ( select item
from tbl
group by item
having count(item) >= 3) t2 on t1.item = t2.item
where t2.item is not null
or in:
select t1.*
from tbl t1
where t1.item in ( select item
from tbl
group by item
having count(item) >= 3)
or exists:
select t1.*
from tbl t1
where exist ( select *
from tbl
where item = t1.item
group by item
having count(item) >= 3)
select * from a t1 where (select count(*) from a t2 where t2.x=t1.x)>2;
a is the table name, x is the first column's name.
Related
We have a set of data where there are 2 records for each CODE. An example of the data is this:
TICKER CODE SCORE PRICE PCF
---------------------------------------
ABC 23 A 100 20
DEF 23 B 200 30
XXX 52 C 300 40
YYY 52 D 400 50
GHI 86 E 500 60
JKL 86 F 600 70
MNO 27 G 700 80
PQR 27 H 800 90
So, what we need to do is create a query which will return the columns of the like records by CODE into 1 record like this:
CODE,TICKER_1,SCORE_1,PRICE_1,PCF_1,TICKER_2,SCORE_2,PRICE_2,PCF_2
23,ABC,A,100,20,DEF,B,200,30
52,XXX,C,300,40,YYY,D,400,40
86,GHI,E,500,60,JKL,F,600,70
27,MNO,G,700,80,PQR,H,800,90
So, that they are combined by like CODE values.
You may try the following which assigns uses ROW_NUMBER to assign a row number for each code entry before using MAX with a case expression to filter for each entry.
Eg.
SELECT
CODE,
MAX(CASE WHEN rn=1 THEN TICKER END) AS TICKER_1,
MAX(CASE WHEN rn=1 THEN SCORE END) AS SCORE_1,
MAX(CASE WHEN rn=1 THEN PRICE END) AS PRICE_1,
MAX(CASE WHEN rn=1 THEN PCF END) AS PCF_1,
MAX(CASE WHEN rn=2 THEN TICKER END) AS TICKER_2,
MAX(CASE WHEN rn=2 THEN SCORE END) AS SCORE_2,
MAX(CASE WHEN rn=2 THEN PRICE END) AS PRICE_2,
MAX(CASE WHEN rn=2 THEN PCF END) AS PCF_2
FROM (
SELECT
m.*,
ROW_NUMBER() OVER (PARTITION BY CODE ORDER BY TICKER) as rn
FROM mytable m
) m1
GROUP BY
CODE
Outputs:
CODE
TICKER_1
SCORE_1
PRICE_1
PCF_1
TICKER_2
SCORE_2
PRICE_2
PCF_2
23
ABC
A
100
20
DEF
B
200
30
27
MNO
G
700
80
PQR
H
800
90
52
XXX
C
300
40
YYY
D
400
50
86
GHI
E
500
60
JKL
F
600
70
For debugging purposes, the output of the subquery
SELECT
m.*,
ROW_NUMBER() OVER (PARTITION BY CODE ORDER BY TICKER) as rn
FROM mytable m
looks like this:
TICKER
CODE
SCORE
PRICE
PCF
RN
ABC
23
A
100
20
1
DEF
23
B
200
30
2
MNO
27
G
700
80
1
PQR
27
H
800
90
2
XXX
52
C
300
40
1
YYY
52
D
400
50
2
GHI
86
E
500
60
1
JKL
86
F
600
70
2
View working demo on db fiddle
Notable alternatives
Instead of CASE WHEN rn=1 THEN TICKER END you could also use the DECODE function available in oracle as DECODE(rn,1,TICKER)
You may also use a pivot as shown below (NB. Column names are not as in the expected result)
WITH cte as (
SELECT
m.*,
ROW_NUMBER() OVER (PARTITION BY CODE ORDER BY TICKER) as rn
FROM mytable m
)
SELECT * FROM cte
PIVOT (
MAX(TICKER) as "TICKER",
MAX(SCORE) as "SCORE",
MAX(PRICE) as "PRICE",
MAX(PCF) as "PCF"
FOR rn IN (1,2)
)
Outputs:
CODE
1_TICKER
1_SCORE
1_PRICE
1_PCF
2_TICKER
2_SCORE
2_PRICE
2_PCF
23
ABC
A
100
20
DEF
B
200
30
27
MNO
G
700
80
PQR
H
800
90
52
XXX
C
300
40
YYY
D
400
50
86
GHI
E
500
60
JKL
F
600
70
View working demo on db fiddle here
For Example:
1 23 12
33 AB1 A1
5 AC4 B5
77 AD9 B5
7 93C 1
.
A B C D E F G
1 EA12 B5
2 B29 7
3 AD9 AC4
7 AB1 1
Result
A B C
1 1 23 null 12 null
33 null AB1 AB1 A1 null
5 5 AC4 AC4 B5 B5
77 null AD9 AD9 B5 B5
7 7 93C null 1 1
I think this is what you need:
with
x as (
select c as v from t2
union select e from t2
union select g from t2
)
select
a,
(case when a in (select v from x) then a end) as found_a,
b,
(case when b in (select v from x) then b end) as found_b,
c,
(case when c in (select v from x) then c end) as found_c
from t1
I am attempting to remove transactions that have been reversed from a table. the table has Account, Date, Amount and Row. If a transaction has been reversed Account will match and Amount will be inverse of each other.
Example Table
Account Date Amount Row
12 1/1/18 45 72 -- Case 1
12 1/2/18 50 73
12 1/2/18 -50 74
12 1/3/18 52 75
15 1/1/18 51 76 -- Case 2
15 1/2/18 51 77
15 1/2/18 -51 78
15 1/2/18 51 79
18 1/2/18 50 80 -- Case 3
18 1/2/18 50 81
18 1/2/18 -50 82
18 1/2/18 -50 83
18 1/3/18 50 84
18 1/3/18 50 85
20 1/1/18 57 88 -- Case 4
20 1/2/18 57 89
20 1/4/18 -57 90
20 1/5/18 57 91
Desired Results Table
Account Date Amount Row
12 1/1/18 45 72 -- Case 1
12 1/3/18 52 75
15 1/1/18 51 76 -- Case 2
15 1/2/18 51 79
18 1/3/18 50 84 -- Case 3
18 1/3/18 50 85
20 1/1/18 57 88 -- Case 4
20 1/5/18 57 91
Removing all instances of inverse transactions does not work when there are multiple transactions when all other columns are the same. My attempt was to count all duplicate transactions, count of all inverse duplicate transactions, subtracting those to get the number of rows I needed from each transactions group. I was going to pull the first X rows but found in most cases I want the last X rows of each group, or even a mix (the first and last in Case 2).
I either need a method of removing pairs from the original table, or working from what I have so far, a method of distinguishing which transactions to pull.
Code so far:
--adding row Numbers
with a as (
select
account a,
date d,
amount f,
row_number() over(order by account, date) r
from table),
--counting Duplicates
b as (
select a.a, a.f, Dups
from a join (
select a, f, count(*) Dups
from a
group by a.a, a.f
having count(*)>1
) b
on a.a=b.a and
b.f=a.f
where a.f>0
),
--counting inverse duplicates
c as (
select a.a, a.f, InvDups
from a join (
select a, f, count(*) InvDups
from a
group by a.a, a.f
having count(*)>1
) b
on a.a=b.a and
-b.f=a.f
where a.f>0
),
--combining c and d to get desired number of rows of each transaction group
d as (
select
b.a, b.f, dups, InvDups, Dups-InvDups TotalDups
from b join c
on b.a=c.a and
b.f=c.f
),
--getting the number of rows from the beginning of each transaction group
select d.a, d.d, d.f
from
(select
a, d, f, row_number() over (group by a, d, f) r2
from a) e
join d
on e.a=d.a and
TotalDups<=r2
You can try this.
SELECT T_P.* FROM
( SELECT *, ROW_NUMBER() OVER(PARTITION BY Account, Amount ORDER BY [Row] ) RN from #MyTable WHere Amount > 0 ) T_P
LEFT JOIN
( SELECT *, ROW_NUMBER() OVER(PARTITION BY Account, Amount ORDER BY [Row] ) RN from #MyTable WHere Amount < 0 ) T_N
ON T_P.Account = T_N.Account
AND T_P.Amount = ABS(T_N.Amount)
AND T_P.RN = T_N.RN
WHERE
T_N.Account IS NULL
The following handles your three cases:
with t as (
select t.*,
row_number() over (partition by account, date, amount order by row) as seqnum
from table t
)
select t.*
from t
where not exists (select 1
from t t2
where t2.account = t.account and t2.date = t.date and
t2.amount = -t.amount and t2.seqnum = t.seqnum
);
Use This
;WITH CTE
AS
(
SELECT
[Row]
FROM YourTable YT
WHERE Amount > 0
AND EXISTS
(
SELECT 1 FROM YourTable WHERE Account = YT.Account
AND [Date] = YT.[Date]
AND (Amount+YT.Amount)=0
)
UNION ALL
SELECT
[Row]
FROM YourTable YT
WHERE Amount < 0
AND EXISTS
(
SELECT 1 FROM YourTable WHERE Account = YT.Account
AND [Date] = YT.[Date]
AND (Amount+YT.Amount)>0
)
)
SELECT * FROM YourTable
WHERE EXISTS
(
SELECT 1 FROM CTE WHERE [Row] = YourTable.[Row]
)
I need to get the sum of all TOTAL fields where the ID, RECNO and DRCR fields have the same value, while also displaying these fields in the result set.
eg
ID RECNO SECRECNO DRCR TOTAL
1 9 5 D 25
1 9 12 D 22
1 9 6 C 33
1 9 5 D 50
1 8 2 D 12
1 8 2 C 23
2 9 5 D 100
So the results of the query should be
ID RECNO SECRECNO DRCR SUM(TOTAL)
1 9 5 D 75
1 9 12 D 22
1 9 6 C 33
1 8 2 D 12
1 8 2 C 23
2 9 5 D 100
This query will give the results set, without the TOTAL:
select distinct t1.recno, t1.secrecno
from table t1, table t2
where t1.recno = t2.recno and t.id = '1' and t1.drcr = 'D'
But I can't see how to SUM the TOTAL of these results.
How to do this?
select t1.id,
t1.recno,
t1.secrecno,
t1.drcr,
SUM( TOTAL )
from table t1
INNER JOIN
table t2
ON ( t1.recno = t2.recno )
WHERE t1.id = '1'
AND t1.drcr = 'D'
GROUP BY
t1.id,
t1.recno,
t1.secrecno,
t1.drcr
table 1
_id sub_id
1 32
2 34
3 42
4 44
5 47
6 50
.
table 2
_id sub_id
1 34
2 42
i want result
_id sub_id count
1 32 2
2 34 2
3 42 1
4 44 0
5 47 0
6 50 0
table 2 sub id 34 contains table 1, above 32 -> count+1
table 2 sub id 42 contains table 1, above 32, 34, 42 -> count + 1
result
32, 34 = 2
42 = 1
44, 47, 50 = 0
i try outer join, left join etc....
not correct result.
how about this correct result?
plz. help me T.T....
Try this query
SELECT _id
,sub_id
,(
SELECT count(*)
FROM table2 t2
WHERE t2.sub_id >= t1.sub_id
) count
FROM table1 t1
This is what you want :
SELECT
t1._id
,t1.sub_id
,count(t2._id) as count
FROM
table1 t1
left join table2 t2
on t2.sub_id >= t1.sub_id
GROUP BY
t1._id
,t1.sub_id
Here is the SQLfiddle demo
select distinct a.id, a.sub_id,
case when c.sub_id is not null then (select count(*) from table2 b
where a.sub_id<=b.sub_id)
else 0 end as counter
from table1 a left join table2 c on c.sub_id>=a.sub_id
SQL Fiddle