哪种SQL在第一列中返回重复项,而第二列中的值不同?

哪种SQL在第一列中返回重复项,而第二列中的值不同?,sql,oracle10g,duplicates,Sql,Oracle10g,Duplicates,这个问题和这个很相似 但我只想找到那些代码不同于“ROME”的重复id,并且至少有一个名称是“ROME”。 我想要期望的结果,因为:1。身份证是重复的。至少有一个来源是“罗马” 3.该ID的其余行不是“ROME” Table ID ORIGIN ----------- 1 ROME 1 ROME 2 ROME 2 LODI 3 ASTI 4 PISA 4 BARI Desired Results ID ORIGIN -----------

这个问题和这个很相似 但我只想找到那些代码不同于“ROME”的重复id,并且至少有一个名称是“ROME”。 我想要期望的结果,因为:1。身份证是重复的。至少有一个来源是“罗马” 3.该ID的其余行不是“ROME”

Table 

ID   ORIGIN
-----------
1    ROME
1    ROME
2    ROME
2    LODI
3    ASTI
4    PISA
4    BARI

Desired Results
ID   ORIGIN
-----------
 2   ROME
 2   LODI 
输出

2罗马 2洛迪

这就产生了你想要的结果。我不确定它对于不同的数据集是否有任何错误。但这会让你朝着正确的方向前进

CREATE GLOBAL TEMPORARY TABLE Test
(
    Id int,
    Origin varchar(100)
)

INSERT INTO #Test
SELECT  1,    'ROME' FROM DUAL UNION ALL
SELECT  1,    'ROME' FROM DUAL UNION ALL
SELECT  2,    'ROME' FROM DUAL UNION ALL
SELECT  2,    'LODI' FROM DUAL UNION ALL
SELECT  3,    'ASTI' FROM DUAL UNION ALL
SELECT  4,    'PISA' FROM DUAL UNION ALL
SELECT  4,    'BARI'

SELECT T.Id, T.Origin FROM #Test T
JOIN Test T2 ON T.Id = T2.Id
WHERE T.Origin = 'ROME' AND T2.Origin != 'ROME' OR T.Origin != 'ROME' AND T2.Origin = 'ROME'

有人在评论中问道,这是否可以写得更笼统一些。它不能,否则我们将无法得到正确的结果PISA和BARI将在表1中的何处旅行。原点!=表2.来源

尽管这是一种可能的解决方案。它太硬了。你能把它一般地写下来吗?如果他不仅仅是和罗马有冲突呢?你对那个ID的剩余行“不是罗马”的确切意思是什么?如果必须至少有一个ROME,这不会使条件3过时吗?是的,条件3是条件2的冗余表达式。更正,条件3用于排除只有id='ROME'id=1的行满足条件1和2,但不满足条件3。这就是为什么我有条件3。我不想要ID=1检查我的答案,我想它能满足你的要求。基本上,这就是我在看你的答案之前所考虑的。但我认为这里的聚合太多了。也许这就足够了:把不同的起源数过。。。作为DistinctOrigins,COUNTDISTINCT CASE当Origin='ROME'然后1结束时。。。作为HasTargetOrigin,然后在外部查询中:其中DistinctOrigins>1,HasTargetOrigin=1。或者Oracle实际上有COUNTDISTINCT?当然Oracle有COUNTDISTINCT。由于所有四个窗口都使用相同的partition by子句,我认为进行聚合不会带来太多开销。
SELECT id,
       origin
FROM (
    SELECT id, 
           origin, 
           count(*) over (partition by id) as id_count,
           count(case when origin = 'ROME' then origin else null end) over (partition by id) as rome_count,
           count(case when origin <> 'ROME' then origin else null end) over (partition by id) as non_rome_count,
           row_number() over (partition by id) as rn

    FROM stuff
) t
WHERE rome_count > 0 
  and non_rome_count > 0
  and id_count > 1
CREATE GLOBAL TEMPORARY TABLE Test
(
    Id int,
    Origin varchar(100)
)

INSERT INTO #Test
SELECT  1,    'ROME' FROM DUAL UNION ALL
SELECT  1,    'ROME' FROM DUAL UNION ALL
SELECT  2,    'ROME' FROM DUAL UNION ALL
SELECT  2,    'LODI' FROM DUAL UNION ALL
SELECT  3,    'ASTI' FROM DUAL UNION ALL
SELECT  4,    'PISA' FROM DUAL UNION ALL
SELECT  4,    'BARI'

SELECT T.Id, T.Origin FROM #Test T
JOIN Test T2 ON T.Id = T2.Id
WHERE T.Origin = 'ROME' AND T2.Origin != 'ROME' OR T.Origin != 'ROME' AND T2.Origin = 'ROME'
SELECT id,
       origin
FROM (
    SELECT id, 
           origin, 
           count(*) over (partition by id) as id_count,
           count(case when origin = 'ROME' then origin else null end) over (partition by id) as rome_count,
           count(case when origin <> 'ROME' then origin else null end) over (partition by id) as non_rome_count,
           row_number() over (partition by id) as rn

    FROM stuff
) t
WHERE rome_count > 0 
  and non_rome_count > 0
  and id_count > 1