MySQL查询数据以行而不是列显示的位置

时间:2014-09-28 21:19:34

标签: mysql

我需要找到订购了一定数量特定产品的所有客户的客户ID。例如,我想获得订购了2个或更多奶酪或5个或更多面包的所有客户ID。这应该给我1,4和3

customerID  product     qty
1           cheese      3
1           bread       2
2           cheese      1
2           pizza       4
3           bread       10
3           tomato      4
4           cheese      2

如果我的桌子结构被改变成有一个用于奶酪,面包,披萨,面包和番茄的柱子,那将会容易得多。不幸的是,这是不可能的。

编辑:customerID / product组合是唯一的。我还希望能够在满足所有条件时进行搜索。所以,3个或更多的奶酪和2个或更多的面包。

3 个答案:

答案 0 :(得分:2)

select distinct customerID from Products
where (product = 'cheese' and qty >= 2) or (product = 'bread' and qty >= 5);

答案 1 :(得分:2)

SELECT t.customerID,
 SUM(CASE WHEN t.product='cheese' THEN quantity ELSE 0 END) as cheese,
 SUM(CASE WHEN t.product='bread' THEN quantity ELSE 0 END) as bread
FROM t
GROUP BY t.customerID
HAVING cheese>=2
OR bread>=5;

FIDDLE

或者为了清晰起见将它们移到HAVING子句

FIDDLE

答案 2 :(得分:1)

编辑我的错......我误读了规范。以下示例返回“奶酪”数量> = 2 AND '面包'数量> = 5的客户。规范适用于 OR 而不是 AND

以下是一个示例(一种可行方法中的一种)返回指定的未指定的结果集...具有BOTH cheese qty> = 2 AND bread qty>的客户= 5:

SELECT a.customer_id
  FROM ( SELECT p.customer_id 
           FROM mytable p
          WHERE p.product         = 'cheese'
          GROUP BY p.customer_id
         HAVING SUM(p.qty)        >= 2
       ) a
  JOIN ( SELECT q.customer_id 
           FROM mytable q
          WHERE q.product         = 'bread'
          GROUP BY q.customer_id
         HAVING SUM(q.qty)        >= 5
       ) b
    ON b.customer_id = a.customer_id

我假设您要检查给定产品的qty并将给定客户作为所有匹配行的“总”数量,而不只是检查指定数量超过指定数量的单个行值。如果您只想检查单个行的数量,则删除聚合上的谓词,即HAVING SUM(qty) >= n,并在WHERE子句AND qty >= n中添加谓词。

编辑为了获得拥有EITHER的客户的结果,我们可以使用类似的方法,获取拥有奶酪数量> = 1的客户列表,并将其与客户列表相结合面包数量> = 5,并获得一个明确的列表。

  ( SELECT p.customer_id 
      FROM mytable p
     WHERE p.product         = 'cheese'
     GROUP BY p.customer_id
    HAVING SUM(p.qty)        >= 2
  ) 
  UNION 
  ( SELECT q.customer_id 
      FROM mytable q
     WHERE q.product         = 'bread'
     GROUP BY q.customer_id
    HAVING SUM(q.qty)        >= 5
  )

还有其他一些方法。您特别询问了如何将“行”更改为“列”。我们通常用来指代那种操作的术语是“pivot”或“pivot table”。

以下是该方法的一个示例:

SELECT t.customer_id
     , SUM(IF(t.product= 'cheese'  ,t.qty,NULL)) AS `qty_cheese`
     , SUM(IF(t.product= 'bread'   ,t.qty,NULL)) AS `qty_bread`
  FROM mytable t
 GROUP BY t.customer_id
HAVING `qty_cheese`  >= 2
    OR `qty_bread`   >= 5

同样,这是检查给定客户和给定产品的“总”数量。如果您只想检查是否存在qty >= n行,请将SUM()聚合函数替换为MAX()

对于mytable返回的每一行,我们正在评估表达式,将product与特定值进行比较,如果匹配,我们将从qty列返回值。

我们通常在SELECT列表中执行此操作,因为它允许我们调试查询,我们可以省略“HAVING”子句,并获取所有客户的列表,并查看每个qty产品

这些表达式不必在SELECT列表中。这些表达式可以移动到HAVING子句。

SELECT t.customer_id
  FROM mytable t
 GROUP BY t.customer_id
HAVING SUM(IF(t.product= 'cheese'  ,t.qty,NULL))  >= 2
    OR SUM(IF(t.product= 'bread'   ,t.qty,NULL))  >= 5

还有其他一些可行的方法。