【问题标题】:SQL Select duplicate rows with specific valuesSQL 选择具有特定值的重复行
【发布时间】:2019-07-06 17:37:36
【问题描述】:

我有一个包含产品数据的表 (JobLog)。我希望能够检查某些字段是否可能已重新提交并输入了两次,但之前可能已被处理过。

我的代码如下:

SELECT A.ProductName, A.ProductCode, A.AmtHeld, A.Disposition
FROM 
    JobLog AS A 
    INNER JOIN (
        SELECT ProductCode, AmtHeld
        FROM JobLog GROUP BY ProductCode, AmtHeld 
        HAVING COUNT(*) > 1
    ) AS B 
        ON (A.ProductCode = B.ProductCode) 
        AND (A.AmtHeld = B.AmtHeld) 

它输出:

|ProductName | AmtHeld | ProductCode | Disposition|
|------------|---------|-------------|------------|
| chocolate  | 123     | 500         | P          |
|------------|---------|-------------|------------|
| chocolate  | 123     | 500         | C          |
|------------|---------|-------------|------------|
| vanilla    | 355     | A30         | C          |
|------------|---------|-------------|------------|
| vanilla    | 355     | A30         | C          |
|------------|---------|-------------|------------|

有什么方法可以有一个附加参数,它只输出具有 Disposition = P 作为行的一部分的行?例如,我只想要两种巧克力产品的输出,因为其中一种具有 P 的性格,而不是两种香草,因为它们都具有 C 的性格(没有 P)。

|ProductName | AmtHeld | ProductCode | Disposition|
|------------|---------|-------------|------------|
| chocolate  | 123     | 500         | P          |
|------------|---------|-------------|------------|
| chocolate  | 123     | 500         | C          |
|------------|---------|-------------|------------|

提前致谢!

【问题讨论】:

    标签: mysql sql ms-access


    【解决方案1】:

    您可以将条件放在HAVING 子句中:

    SELECT A.ProductName, A.ProductCode, A.AmtHeld, A.Disposition
    FROM JobLog AS A INNER JOIN 
        (SELECT ProductCode, AmtHeld
         FROM JobLog
         GROUP BY ProductCode, AmtHeld 
         HAVING COUNT(*) > 1 AND
                SUM(IIF(DISPOSITION = 'P', 1, 0)) > 0
        ) AS B
        ON A.ProductCode = B.ProductCode AND 
           A.AmtHeld = B.AmtHeld 
    

    【讨论】:

      【解决方案2】:

      您可以在查询中添加WHERE EXISTS 子句,以检查表中某处的Disposition 值为P 的产品:

      WHERE EXISTS (SELECT * 
                    FROM JobLog A1
                    WHERE A1.ProductCode = A.ProductCode AND A1.Disposition = 'P')
      

      或者你可以做另一个自我加入:

      JOIN JobLog C
      ON C.ProductCode = A.ProductCode AND C.Disposition = 'P'
      

      【讨论】:

        【解决方案3】:

        我相信不使用聚合就可以满足您的要求。您可以简单地使用 WHERE EXISTS 条件来确保当前 ProductCode/AmtHeld 元组至少有两条记录,并且其中一条具有处置 P。

        SELECT A.ProductName, A.ProductCode, A.AmtHeld, A.Disposition
        FROM JobLog AS A 
        WHERE EXISTS (
            SELECT 1 FROM JobLog B
            WHERE 
                A.ProductCode = B.ProductCode 
                AND A.AmtHeld = B.AmtHeld
                AND A.Disposition <> B.Disposition
                AND (A.Disposition = 'P' OR B.Disposition = 'P') 
        )
        

        This DB Fiddle 与您的示例数据返回:

        |产品名称 |产品代码 | AmtHeld |处置 | | ------------ | ------------ | -------- | ------------ | |巧克力| 高分辨率照片| CLIPARTO 500 | 123 |磷 | |巧克力| 高分辨率照片| CLIPARTO 500 | 123 | C |

        【讨论】: