【问题标题】:WHERE/GROUP By Condition - One Name but multiple valuesWHERE/GROUP By Condition - 一个名称但多个值
【发布时间】:2018-05-04 17:20:12
【问题描述】:

我有下表:

Name          Product         
Bob           Car              
Bob           Apples
Bob           Pears
Bob           Car
John          Apples
John          Pears

无论谁购买了 Product Car,我都希望与其他人保持距离。所以,我创建了一个标志:

Name          Product       Flag        
Bob           Car             1  
Bob           Apples          0
Bob           Pears           0  
Bob           Car             1
John          Apples          0
John          Pears           0 

但我的标志的问题在于,即使我执行 where 条件并说,向我展示消费者 WHERE 标志!=1,它也会选择 Bob。这是不正确的,因为 Bob 拥有汽车。

我仍想按产品分组。

如何将上表分成两组?

谢谢!

【问题讨论】:

  • 您根本不需要Flag 列。
  • "如何将上表分成两组?" - 什么“团体”?请注意,SQL 中的GROUP BY 不会在输出中“分组”结果集,而是用于聚合函数的应用。请发布一些示例所需的输出,因为您的问题不清楚。
  • 您根本不需要Flag 列。如果您的目的是对特定用户隐藏 Name 列,则必须创建一个基本上是 SELECT all_columns_except_name FROM your_table 的 VIEW,然后设置特定权限:普通用户无法访问该表,但可以访问该视图

标签: mysql sql hql


【解决方案1】:

使用下面的查询:-

select name from table where flag!=1
and name not in (select name from table where flag = 1)
group by name

【讨论】:

    【解决方案2】:

    “告诉我消费者 WHERE 标志!=1,它会选择 Bob”,这是因为您要求 rows where flag != 1。相反,您需要更多的东西复杂的,比如:

    SELECT DISTINCT Name
    FROM tableTable
    WHERE Name NOT IN (SELECT Name FROM theTable WHERE Product = 'Car')
    

    或者,您可以执行 LEFT JOIN,这可能会或可能不会更快,具体取决于您拥有的数据量及其值的分布方式。

    SELECT DISTINCT a.Name
    FROM theTable a
    LEFT JOIN theTable b ON a.Name = b.Name AND b.Product = 'Car'
    WHERE a.Product != 'Car' AND b.Product IS NULL
    ;
    

    这会获取除汽车以外的所有产品行,然后使用 LEFT JOIN 结合 IS NULL 条件来查找没有“汽车”行的行。

    【讨论】:

      【解决方案3】:

      我认为您希望显示您的表的数据,只是以某种方式将“购买汽车的人”分区(未分组)分开 - 例如,这可以通过 ORDER BY OwnsACar 子句来完成。

      第 1 步:确定购买汽车的人:

      SELECT DISTINCT
          Name
      FROM
          yourTable
       WHERE
          Product = 'Car'
      

      第 2 步:加入此数据以生成计算得出的“OwnsACar”列:

      SELECT
          yourTable.Name,
          yourTable.Product,
          ISNULL( carowners.Name ) AS OwnsACar
      FROM
          yourTable
          LEFT OUTER JOIN
          (
              SELECT DISTINCT
              Name
          FROM
              yourTable
          WHERE
              Product = 'Car'
          ) AS carowners ON carowners.Name = yourTable.Name
      ORDER BY
          OwnsACar ASC,
          yourTable.Name ASC
      

      【讨论】:

        【解决方案4】:

        您可以使用这两个查询。不需要额外的Flag 列。

        -- do not have Car
        SELECT * 
        FROM products
        WHERE Name not in (SELECT DISTINCT Name 
                           FROM products 
                           WHERE Product='Car');
        
        -- have Car
        SELECT * 
        FROM products
        WHERE Name in (SELECT DISTINCT Name 
                       FROM products 
                       WHERE Product='Car');
        

        插图:

        -- table
        SELECT * FROM products;
        +------+---------+
        | Name | Product |
        +------+---------+
        | Bob  | Car     |
        | Bob  | Apples  |
        | Bob  | Pears   |
        | Bob  | Car     |
        | John | Apples  |
        | John | Pears   |
        +------+---------+
        
        -- query for people that do not have Car
        +------+---------+
        | Name | Product |
        +------+---------+
        | John | Apples  |
        | John | Pears   |
        +------+---------+
        
        
        -- query for people having 'Car'
        +------+---------+
        | Name | Product |
        +------+---------+
        | Bob  | Car     |
        | Bob  | Apples  |
        | Bob  | Pears   |
        | Bob  | Car     |
        +------+---------+
        

        【讨论】:

          【解决方案5】:

          尝试:

          SELECT `t`.`Name`, `t`.`Product`, SUM(`t`.`Flag`) as hasCar
          FROM your_table t
          GROUP BY `t`.`Name`
          HAVING `t`.`hasCar` = 0;
          

          尽管您可以通过以下方式不使用标志列:

          SELECT `t`.`Name`, `t`.`Product`, SUM(IF(`t`.`Product` = 'Car', 1, 0)) as hasCar
          FROM your_table t
          GROUP BY `t`.`Name`
          HAVING `t`.`hasCar` = 0;
          

          【讨论】:

          • 使用正确的GROUP BYSELECT * ... GROUP BY t.Name 甚至无法在 99% 的 dbms 上运行。
          • 根本没明白你的意思。只是添加了反引号以避免可能的关键字问题,如果那是您所指的 + 这被标记为 mysql。
          • 使用GROUP BY时需要列出列名。
          • 在这种情况下,mysql 不需要,但无论如何,我更新了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-13
          • 2014-11-22
          • 1970-01-01
          • 2020-10-30
          • 2018-01-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多