Find multiply duplicates in row ORACLE [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
We have the following table:
create table tab(
id number,
date number,
date2 number
)
We need to find rows, if they have date==date2.
Im trying like this:
SELECT date,date2, COUNT(*)
FROM tab
GROUP BY date,date2
HAVING COUNT(*) > 1
But I cant get FULL ROW with ID. how to write a query correctly?

Sample data (with a note that column name can't be just date as it is reserved for the DATE datatype).
SQL> select * from tab;
ID DATUM DATUM2
---------- ---------- ----------
1 26.12.2022 26.12.2022
2 13.08.2022 22.11.2022
3 26.12.2022 26.12.2022
We need to find a rows, if they have date==date2.
That's just
SQL> select * from tab where datum = datum2;
ID DATUM DATUM2
---------- ---------- ----------
1 26.12.2022 26.12.2022
3 26.12.2022 26.12.2022
On the other hand, you said
i cant get FULL ROW with ID
based on query you posted. It might be adjusted:
SQL> select * from tab
2 where (datum, datum2) in (select datum, datum2
3 from tab
4 group by datum, datum2
5 having count(*) > 1
6 );
ID DATUM DATUM2
---------- ---------- ----------
1 26.12.2022 26.12.2022
3 26.12.2022 26.12.2022
SQL>
if that's what you're looking for.

Related

analytical functions

good afternoon, a question, how can I optimize the code, I don't know, maybe using oracle analytical functions :
-- tabledeuda : this table contains 2 months 202212 and 202211
SELECT B.*,
NVL(B.DEUDAPRESTAMO_PAGPER,0)-NVL(A.DEUDAPRESTAMO_PAGPER,0) AS SALE_CT -- current month - previous month
FROM tabledeuda B
LEFT JOIN tabledeuda A ON (A.CODLLAVE = B.CODLLAVE
AND A.CODMES = TO_NUMBER(TO_CHAR(ADD_MONTHS(TO_DATE(B.CODMES,'YYYYMM'),-1),'YYYYMM'))
AND A.financial_company = B.financial_company
AND A.CODMONEY=B.CODMONEY)
WHERE NVL(B.DEUDAPRESTAMO_PAGPER,0)>NVL(A.DEUDAPRESTAMO_PAGPER,0)
AND B.CODMES = &CODMES; ---> &CODMES 202212
OUTPUT
Looks like a candidate for lag analytic function.
Sample data is rather poor so it is unclear what happens when there's more data, but - that's the general idea.
Sample data:
SQL> with test (codmes, customer, deudaprestamo_pagper) as
2 (select 202212, 'T1009', 200 from dual union all
3 select 202211, 'T1009', 150 from dual
4 )
Query:
5 select codmes, customer,
6 deudaprestamo_pagper,
7 deudaprestamo_pagper -
8 lag(deudaprestamo_pagper) over (partition by customer order by codmes) sale_ct
9 from test;
CODMES CUSTO DEUDAPRESTAMO_PAGPER SALE_CT
---------- ----- -------------------- ----------
202211 T1009 150
202212 T1009 200 50
SQL>
If you want to fetch only the last row (sorted by codmes), you could e.g.
6 with temp as
7 (select codmes, customer,
8 deudaprestamo_pagper,
9 deudaprestamo_pagper -
10 lag(deudaprestamo_pagper) over (partition by customer order by codmes) sale_ct,
11 --
12 row_number() over (partition by customer order by codmes desc) rn
13 from test
14 )
15 select codmes, customer, deudaprestamo_pagper, sale_ct
16 from temp
17 where rn = 1;
CODMES CUSTO DEUDAPRESTAMO_PAGPER SALE_CT
---------- ----- -------------------- ----------
202212 T1009 200 50
SQL>

Count values separately until certain amount of duplicates SQL

I need a Statement that selects all patients and the amount of their appointments and when there are 3 or more appointments that are taking place on the same date they should be counted as one appointment
That is what my Statement looks so far
SELECT PATSuchname, Count(DISTINCT AKTDATUM) AS AKTAnz
FROM tblAktivitaeten
LEFT OUTER JOIN tblPatienten ON (tblPatienten.PATID=tblAktivitaeten.PATID)
WHERE (AKTDeleted<>'J' OR AKTDeleted IS Null)
GROUP BY PATSuchname
ORDER BY AKTAnz DESC
The result should look like this
PATSuchname Appointments
----------------------------------------
Joey Patner 13
Billy Jean 15
Example Name 13
As you can see Joey Patner has 13 Appointments, in the real table though he has 15 appointments but three of them have the same Date and because of that they are only counted as 1
So how can i write a Statement that does exactly that?
(I am new to Stack Overflow, sorry if the format I use is wrong and tell me if it is.
In the table it looks like this.
tblPatienten
----------
PATSuchname PATID
------------------------
Joey Patner 1
Billy Jean 2
Example Name 3
tblAktivitaeten
----------
AKTDatum PATID AKTID
-----------------------------------------
08.02.2021 1 1000 ----
08.02.2021 1 1001 ---- So these 3 should counted as 1
08.02.2021 1 1002 ----
09.05.2021 1 1003
09.07.2021 2 1004 -- these 2 shouldn't be counted as 1
09.07.2021 2 1005 --
Two GROUP BY should do it:
SELECT
x.PATID, PATSuchname, SUM(ApptCount)
FROM (
SELECT
PATID, AKTDatum, CASE WHEN COUNT(*) < 3 THEN COUNT(*) ELSE 1 END AS ApptCount
FROM tblAktivitaeten
GROUP BY
PATID, AKTDatum
) AS x
LEFT JOIN tblPatienten ON tblPatienten.PATID = x.PATID
GROUP BY
x.PATID, PATSuchname

How to join multiple rows by continue from and to id columns in oracle

I have a scenario where I need to find the start date and end date from multiple rows which are tied by continued_from and continued_to date fields in Oracle.
result should look like
ID STARTDATE ENDDATE
-- ---------- ----------
3 01/01/1000 12/31/9999
ID STARTDATE ENDDATE CONT_FROM_ID CONT_TO_ID
-- ---------- ---------- ------------ -----------
1 01/01/1000 10/10/1999 NULL 2
2 10/10/1999 11/11/2000 1 3
3 11/11/2000 12/31/9999 2 NULL
Oracle's hierarchical query syntax makes it easy to walk the tree from parent to child. The analytical lead() and lag() functions track the next and previous IDs.
select c23.id
, c23.startdate
, c23.enddate
, lag(c23.id) over (partition by p23.id order by c23.id) as cont_from_id
, lead(c23.id) over (partition by p23.id order by c23.id) as cont_to_id
from p23
join c23 on p23.startdate <= c23.startdate
and p23.enddate >= c23.enddate
order by c23.id
/
Here is a test using your sample data:
SQL> select c23.id
2 , c23.startdate
3 , c23.enddate
4 , lag(c23.id) over (partition by p23.id order by c23.id) as cont_from_id
5 , lead(c23.id) over (partition by p23.id order by c23.id) as cont_to_id
6 from p23
7 join c23 on p23.startdate <= c23.startdate
8 and p23.enddate >= c23.enddate
9 order by c23.id
10 /
ID STARTDATE ENDDATE CONT_FROM_ID CONT_TO_ID
---------- --------- --------- ------------ ----------
1 01-JAN-00 10-OCT-99 2
2 10-OCT-99 11-NOV-00 1 3
3 11-NOV-00 31-DEC-99 2
SQL>

how to select a unique record in a table which has no key constraints [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 7 years ago.
I had a table named uniq_select_records with the following columns:
sno number,
item_name varchar2(50),
start_date date,
end_date date,
action_flag char(1),
last_modified_date date,
creation_date date
sno is a column which I used to identify a row for a item_name and it is not unique or primary key but it was not null. sno will be present for each item. no of items is equal to no of sno. sample
sno item_name start_date end_date Action_flag last_modified creation_date
--- --------- ---------- -------- ----------- ------------- -------------
1 sample1 02-MAY-15 27-MAY-14 A 07-MAY-15 02-MAY-15
1 sample1 02-MAY-15 27-MAY-14 D 07-MAY-15 02-MAY-15
1 sample1 27-APR-15 06-JUN-14 C 07-MAY-15 02-MAY-15
1 sample1 27-APR-15 06-JUN-14 C 07-MAY-15 03-MAY-15
2 sample2 07-MAY-15 11-FEB-15 C 07-MAY-15 22-JAN-15
2 sample2 07-MAY-15 11-FEB-15 A 07-MAY-15 22-JAN-15
2 sample2 07-MAY-15 01-FEB-15 C 12-MAY-15 12-MAY-15
Action flag values C=change, D='Deleted and A=insert
sample data is shown above. like this we have millions of records. now we have to select the to record which had the latest change for each item. each item may have its own start_date and end_date.All the items weren't modified on the same date.
Can anyone suggest idea how to fetch the records for each item which are latest change for an item.
thanks in advance.
SELECT sno, item_name, max(last_modified)
FROM uniq_select_records
GROUP BY sno, item_name

Coalescing values in a column over a partition

I have chosen to ask this question via an example as I think it most clearly illustrates what I am trying to do.
Say I have the following table:
member number time
------ ----- -----
1 2 19:21
1 4 19:24
1 27 19:37
2 4 19:01
2 7 21:56
2 8 22:00
2 21 22:01
How can I obtain the following column?
member number new column
------ ----- ---------
1 2 2.4.27
1 4 2.4.27
1 27 2.4.27
2 4 4.7.8.21
2 7 4.7.8.21
2 8 4.7.8.21
2 21 4.7.8.21
EDIT(S):
I am using DB2 SQL.
There is not necessarily the same number of rows for each member.
The order is determined by time say.
depending on your version of db2, the LISTAGG() function may be available to you. i think it is included in any db2 version after 9.7.
example:
select
member,
number,
listagg(number,',') as new_column
from
tablename
group by
member
In Oracle this will do the job,
select a.member,a.number,b.newcol from table a,(select member,replace(wm_concat(number),',','.') newcol from test11 group by member)b where a.member=b.member;
I know it's bad form answering your own question but I have found this useful page:
https://www.ibm.com/developerworks/mydeveloperworks/blogs/SQLTips4DB2LUW/entry/aggregating_strings42?lang=en
Modifying the code there gives:
create table test (member int, number int, time_stamp time)`;
insert into test values
(1,2,'19:21'),
(1,4,'19:24'),
(1,27,'19:37'),
(2,4,'19:01'),
(2,7,'21:56'),
(2,8,'22:00'),
(2,21,'22:01');
select
member, substr(xmlcast(xmlgroup('.' || number as a order by time_stamp) as varchar(60)), 2)
from test
group by member