I have this table (sales_lines):
id sale_id sale_seq_id other_fields
----------------------------------------
1 1 1
2 1 2
3 2 1
4 3 1
5 3 2
But this table can have a duplicated sale_seq_id (yes, it's an error). Like this:
id sale_id sale_seq_id other_fields
----------------------------------------
1 1 1
2 1 2
3 1 2
4 2 1
5 3 1
6 3 1
7 3 2
Lines 3 and 6 are errors, so I should discard them.
How can I do it?
To delete the wrong records do
delete from sales_lines
where id not in
(
select min(id)
from sales_lines
group by sale_id, sale_seq_id
)
To just delete the correct data do
select min(id), sale_id, sale_seq_id
from sales_lines
group by sale_id, sale_seq_id
I would use correlated sub-query :
select sl.*
from sales_line sl
where sl.id = (select min(sl1.id)
from sales_line sl1
where sl1.sale_id = sl.sale_id and
sl1.sale_seq_id = sl.sale_seq_id
);
If your DBMS supports window function then you can do :
select sl.*
from (select sl.*,
row_number() over (partition by sl.sale_id, sl.sale_seq_id order by sl.id) as seq
from sales_line sl
) sl
where seq = 1;
By this way, you will get full row with other fields too.
I am trying to select the last change value per group.
I have a table
MMID column is incremental
MMID GID MID Value Bundle DateEntered
1 1 1 1 2 17/8/15 05:05:04
2 1 2 2 3 16/8/15 05:05:06
3 1 3 3 2 15/8/15 05:05:07
4 1 1 0 2 18/8/15 05:05:08
5 2 2 1 1 18/8/15 05:05:05
6 2 2 2 2 18/8/15 06:06:06
7 2 4 3 1 17/8/15 06:06:06
8 2 4 3 2 18/8/15 06:06:07
Here, I want the last change 'Value' in the last 24 hour(Having Date 18th August).
From the below query, I can get that. But even if the bundle value is changed, then I get that row.
But I want only rows when 'Value' is changed, or 'Value and Bundle' are changed. But not only when Bundle is changed
Desired output
MMID GID MID Value Bundle DateEntered
4 1 1 0 2 18/8/15 05:05:08
6 2 2 2 2 18/8/15 06:06:06
The query I tried is :
select yt1.*
from Table1 yt1
left outer join Table1 yt2
on (yt1.GID = yt2.GID and yt1.MID = yt2.MID
and yt1.MMID < yt2.MMID)
where yt2.MMID is null and yt2.GID is null and yt2.MID is null and yt1.DateEntered > '2015-08-18 00:00:00' ;
The output i get from here is:
MMID GID MID Value Bundle DateEntered
4 1 1 0 2 18/8/15 05:05:08
6 2 2 2 2 18/8/15 06:06:06
8 2 4 3 2 18/8/15 06:06:07
I should not be getting the last row here.
Can anyone tell me what should I change here.
Not really following the logic of your attempt, but here is how I would get the desired results:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY GID, MID ORDER BY MMID) AS rn
FROM Table
)
, cte2 AS (
SELECT t1.* FROM cte t1
INNER JOIN cte t2
ON t1.GID=t2.GID
AND t1.MID=t2.MID
AND t1.value<>t2.value
AND t1.rn=t2.rn+1
)
SELECT *
FROM cte2
WHERE MMID=(
SELECT TOP 1 MMID
FROM cte2 c2
WHERE cte2.GID=c2.GID
AND cte2.MID=c2.MID
ORDER BY MMID DESC
)
NB: If you don't want to include the rn column in the final results, use a column list instead of SELECT *.
I have this table my_table_c with the below values
SELECT * FROM my_table_c
ID GROUP_ID GROUP_VALUE
1 2 1
3 3 2
3 4 1
5 4 1
5 2 1
2 2 2
2 3 2
2 4 1
I am looking for this output where I get only the ID which do not have group_id 2. Additionally, I don't want to get the ID where group_id 2 is absent but other group ids are present.
If group_id 2 is absent, that's my target id.
So with the values shown in table above, I just expect ID = 3 to be returned as other ids 1, 5 and 2 each have rows where group_id = 2.
Can anyone please help with a query to fetch this result.
You could get all the id's that have group_id = 2 and use NOT IN
select *
from my_table_c
where id not in (select id from my_table_c where group_id = 2)
Another way but using NOT EXISTS
select *
from my_table_c mtcA
where not exists (select *
from my_table_c mtcB
where mtcA.id = mtcB.id and mtcB.group_ID = 2)
I have a table with 2 columns A, and B that represent a connection graph between the two.
A B
1 3
2 5
4 2
3 5
2 3
I need to find how many instances of column A occur in column B (including 0)
So for the example above I would need the result set
A OccurencesInB
1 0
2 1
3 2
4 0
The best I have so far is
SELECT B, COUNT(*) AS TABLE_COUNT
FROM TABLE
GROUP BY B
ORDER BY TABLE_COUNT DESC
This does not find the instances of A that do not occur in B, which is crucial.
Any assistance will be greatly appreciated!
Use a correlated sub-query:
SELECT A,
TABLE_COUNT = (SELECT COUNT(*)
FROM TableName t2
WHERE t2.B = t1.A)
FROM TableName t1
GROUP BY A
ORDER BY TABLE_COUNT DESC, A
Result:
A TABLE_COUNT
3 2
2 1
1 0
4 0
My SQL query returns results with 4 columns "A", "B", "C", "D".
Suppose the results are:
A B C D
1 1 1 1
1 1 1 2
2 2 2 1
Is it possible to get the count of duplicate rows with columns "A", "B", "C" in each row.
e.g. the expected result is:
A B C D cnt
1 1 1 1 2
1 1 1 2 2
2 2 2 1 1
I tried using count(*) over. But it returns me the total number of rows returned by the query.
Another information is that in example I have mentioned only 3 columns based on which I need to check the count. But my actual query has such 8 columns. And number of rows in database are huge. So I think group by will not be a feasible option here.
Any hint is appreciable.
Thanks.
Maybe too late, but probably the count over as analytic function (aka window function) within oracle helps you. When I understand your request correctly, this should solve your problem :
create table sne_test(a number(1)
,b number(1)
,c number(1)
,d number(1)
,e number(1)
,f number(1));
insert into sne_test values(1,1,1,1,1,1);
insert into sne_test values(1,1,2,1,1,1);
insert into sne_test values(1,1,2,4,1,1);
insert into sne_test values(1,1,2,5,1,1);
insert into sne_test values(1,2,1,1,3,1);
insert into sne_test values(1,2,1,2,1,2);
insert into sne_test values(2,1,1,1,1,1);
commit;
SELECT a,b,c,d,e,f,
count(*) over (PARTITION BY a,b,c)
FROM sne_test;
A B C D E F AMOUNT
-- -- -- -- -- -- ------
1 1 1 1 1 1 1
1 1 2 4 1 1 3
1 1 2 1 1 1 3
1 1 2 5 1 1 3
1 2 1 1 3 1 2
1 2 1 2 1 2 2
2 1 1 1 1 1 1
To find duplicates you must group the data based on key column
select
count(*)
,empno
from
emp
group by
empno
having
count(*) > 1;
This allows you to aggregate by empno even when multiple records exist for each category (more than one).
You have to use a subquery where you get the count of rows, grouped by A, B and C. And then you join this subquery again with your table (or with your query), like this:
select your_table.A, your_table.B, your_table.C, your_table.D, cnt
from
your_table inner join
(SELECT A, B, C, count(*) as cnt
FROM your_table
GROUP BY A, B, C) t
on t.A = your_table.A
and t.B = your_table.B
and t.C = your_table.C