Get duplicate on single column after distinct across multiple columns in SQL - sql

I have a table that looks like this:
name | id
-----------
A 1
A 1
B 2
C 1
D 3
D 3
F 2
I want to return id's 1 and 2 because they are duplicate on names. I don't want to return 3, because it is distinct for D 3.
Basically, I'm thinking of doing a query to first get a distinct pairing, so the above reduces to
name | id
-----------
A 1
B 2
C 1
D 3
F 2
And then doing a duplicate find on the id column. However, I'm struggling to find the correct syntax to construct that query.

You should be able to get the result you want by using a GROUP BY along with a HAVING clause that counts the distinct names. The HAVING clause will filter for those ids that have more than one distinct name:
select id
from Table1
group by id
having count(distinct name) > 1
Here is a demo

Related

How to get an index of different category returned by "order by" sql in oracle?

We can easily get a sql result as following:
SQL>select Name, Value from table order by Name;
Name Value
------------
A 1
A 2
B 1
C 5
C 6
C 7
However, is there a way to link the name to a number so that an index of different names can be formed? Suppose we don't know how many different names are in the table and don't know what they are.
Name Value idx
-----------------
A 1 0
A 2 0
B 1 1
C 5 2
C 6 2
C 7 2
This can easily be done using a window function:
select Name,
Value,
dense_rank() over (order by name) - 1 as idx
from table
order by Name;

Using with CUBE on the same column twice to output perculated results

Hypothetically, I have a table that consists of int values only one column with values like 1,2,3 etc., called Number.
When I try:
SELECT Number,Number FROM Table Group By Number WITH CUBE
It returns:
Number Number
------ ------
1 1
2 2
3 3
I was expecting it to return something more like this:
Number Number
------ ------
1 1
1 2
1 3
2 1
2 2
2 3
and so forth... (with every combination)
How would this be possible, WITH CUBE doesn't seem to be cutting it here.
It seems you want the cartesian product:
SELECT a.Number, b.Number
FROM [Table] a, [Table] b
Or, another way to write:
SELECT a.Number, b.Number
FROM [Table] a CROSS JOIN [Table] b

SQL select Name entries for which a certain requirement is NEVER fulfilled

I need to select Name entries for which none of the rows fulfills a certain requirement. This is best described as an example- lets consider the following table:
Name Number ID
A 1 2
A 2 2
B 1 2
B 2 3
C 3 3
The requirement would be that Number=ID. For the name B this is never the case, so I would like to return the Name B.
Name Number ID
A 1 2
A 2 2 <---- fulfills requirement for A
B 1 2
B 2 3
C 3 3 <---- fulfills requirement for C
Is this possible in SQL?
You can use a NOT EXISTS clause
select * from Table1 t1
where not exists (select null
from Table1
where t1.Name = Name
and Number = Id)
If you just want the names which don't fulfill the requirement, just change the select to
select distinct t1.Name
see SqlFiddle with both versions.
Try this
Select Name
from table
where name not in (Select distinct name from table where number = id )

Get rows with single values using SQlite

By using SQlite, I'd like to get all rows that show in a specific column only one single distinct value. Like from following table:
A B
1 2
2 1
3 2
4 3
5 1
6 1
7 2
8 4
9 2
Here I'd like to get only row Nr. 4 an 8 as there values (3 and 4) occur only once in the entire column.
You could use a query like this:
SELECT *
FROM mytable
WHERE B IN (SELECT B FROM mytable GROUP BY B HAVING COUNT(DISTINCT A)=1)
Please see fiddle here.
Subquery will return all B values that are present only once (you could also use HAVING COUNT(*)=1 in this case), the outer query will return all rows where B is returned by the subquery.

Count number of not exist in child table

Essentially what I'm trying to do is count the number of rows something doesn't exist in an audit/history table. I'd like the following query to return a count of one per detail. Currently it gives me one per row in the history table.
--Detail Table
ID DETAIL_GROUP
1 A
2 B
3 B
--Detail History Table
DETAIL_ID_FK VALUE1
1 NOT_MATCH
1 NOT_MATCH
2 MATCH
2 NOT_MATCH
3 MATCH
3 NOT_MATCH
SELECT D.DETAIL_GROUP, COUNT(*)
FROM DETAIL D
WHERE (NOT EXISTS(
SELECT NULL
FROM DETAIL_HISTORY HI
WHERE HI.D_ID_FK = D.ID
AND HI.VALUE1 = 'MATCH'))
GROUP BY D.DETAIL_GROUP;
I'd like to see the following result:
DETAIL_GROUP COUNT(*)
A 1
but I'm receiving the following result:
DETAIL_GROUP COUNT(*)
A 2
Thank you in advance for any assistance provided.
Assuming that your detail table is as follows:
D_ID VALUE1
1 MATCH
1 NOT_MATCH
2 MATCH
2 NOT_MATCH
3 MATCH
3 NOT_MATCH
The below query:
SELECT d.detail_group, count(*)
FROM detail d
JOIN detail_history dh ON dh.d_id = d.id
WHERE dh.value1 = 'MATCH'
GROUP BY d.detail_group
Would produce:
DETAIL_GROUP COUNT(*)
A 1
B 2
The above query creates the groups matching the ids and then goes into each group and restricts the items based on value1.