【问题标题】:Sql query for group by product barcode if product has barcode and all products having no barcode如果产品有条形码并且所有产品都没有条形码,则按产品条形码查询分组
【发布时间】:2017-01-11 09:33:17
【问题描述】:

我收集了一些产品,其中有些产品有条形码,有些没有。所以,我想显示所有没有任何条形码的产品,如果任何产品有条形码,那么它们将按条形码分组,以便我只能显示一个。

假设,我在下表中有产品:

ID    Name        Barcode  
 1    ABC         349377934434  
 2    DEF         349377934434  
 3    XYZ         NULL  
 4    XXX         NULL

根据上面给出的数据,我的查询应该只给出 3 个产品,即 1 或 2、3 和 4。
上述条件的 sql 查询将是什么?我想在单个查询中获取数据。我不想在我的代码中使用循环来查找上述条件的产品。

请帮我写这篇文章?提前致谢

【问题讨论】:

    标签: php mysql sql-server


    【解决方案1】:
    ;WITH cte
    AS
    (
        SELECT ID, Name, Barcode
        FROM (
            VALUES
            (1, 'ABC', '349377934434'),
            (2, 'DEF', '349377934434'),
            (3, 'XYZ', NULL),
            (4, 'XXX', NULL),
            (5, 'ABC1', '34937'),
            (6, 'DEF1', '34937'),
            (7, 'DEF2', '34937')
        )v(ID, Name, Barcode)
    )
    
    SELECT DISTINCT v.ID, v.Name, c.Barcode
    FROM cte c
        CROSS APPLY (SELECT TOP 1 ID, Name FROM cte WHERE Barcode = c.Barcode) v
    WHERE c.Barcode IS NOT NULL
    UNION
    SELECT ID, Name, Barcode
    FROM cte c
    WHERE c.Barcode IS NULL
    

    对于 MySQL(我不知道如何在 MySQL 中使用临时表,所以我创建/删除简单表“temp”):

    CREATE TABLE temp(id INT, name VARCHAR(20), barcode VARCHAR(20));
        INSERT INTO temp SELECT 1, 'ABC', '349377934434';
        INSERT INTO temp SELECT 2, 'DEF', '349377934434';
        INSERT INTO temp SELECT 3, 'XYZ', NULL;
        INSERT INTO temp SELECT 4, 'XXX', NULL;
        INSERT INTO temp SELECT 5, 'ABC1', '34937';
        INSERT INTO temp SELECT 6, 'DEF1', '34937';
        INSERT INTO temp SELECT 7, 'XYZ2', '34937';
    
        SELECT DISTINCT v.ID, v.Name, c.Barcode
        FROM temp c
            INNER JOIN temp v ON v.ID = (SELECT ID FROM temp WHERE Barcode = c.Barcode LIMIT 1)
        WHERE c.Barcode IS NOT NULL
        UNION
        SELECT ID, Name, Barcode
        FROM temp
        WHERE Barcode IS NULL;
    
        DROP TABLE temp;
    

    【讨论】:

    • 感谢您的回复。我们如何在 Mysql 中实现这一点?
    • 谢谢。这就是我一直在寻找的东西。
    【解决方案2】:

    看到您将 SQL Server 包含在列表中,下面是一个将在那里运行的示例:

    DECLARE @table TABLE (id INT, name VARCHAR(20), barcode VARCHAR(20));
    INSERT INTO @table SELECT 1, 'ABC', '349377934434';
    INSERT INTO @table SELECT 2, 'DEF', '349377934434';
    INSERT INTO @table SELECT 3, 'XYZ', NULL;
    INSERT INTO @table SELECT 4, 'XXX', NULL;
    WITH Summary AS (
        SELECT
            ISNULL(barcode, CONVERT(VARCHAR(50), NEWID())) AS barcode,
            MAX(name) AS name
        FROM
            @table
        GROUP BY
            ISNULL(barcode, CONVERT(VARCHAR(50), NEWID())))
    SELECT
        CASE WHEN barcode LIKE '%-%' THEN NULL ELSE barcode END AS barcode,
        name
    FROM
        Summary;
    

    这很不言自明,我按条形码分组,在有重复项的地方按名称取顶部结果。如果条形码为 NULL,我将其替换为随机 GUID,然后在最后将其删除。

    结果是:

    barcode         name
    349377934434    DEF
    NULL            XXX
    NULL            XYZ
    

    【讨论】:

    • 感谢您的回复。我们如何在 Mysql 中实现这一点?
    【解决方案3】:

    如何将 UNION 与 CTE 一起使用:

    设置

    CREATE TABLE #Products
    ( ID int,
      Name VARCHAR(5),
      BarCode VARCHAR(15) NULL
    )
    
    INSERT INTO #Products
    VALUES (1, 'ABC', '349377934434'),
           (2, 'DEF', '349377934434'),  
           (3, 'XYZ', NULL),  
           (4, 'XXX', NULL)
    

    查询:

    ;WITH CTE
    As
    (
        SELECT ID, Name, BarCode, ROW_NUMBER() OVER (Partition By BarCode ORDER BY ID) AS RN
        FROM #Products  
        WHERE BarCode is NOT Null
    )
    SELECT ID, Name, BarCode
    FROM #Products
    WHERE BarCode is Null
    UNION
    SELECT ID, Name, BarCode
    FROM CTE
    WHERE RN = 1
    
    DROP TABLE #Products
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      相关资源
      最近更新 更多