Mysql:如何检索具有相同ID但列中值不同的两行

时间:2019-10-29 06:05:16

标签: mysql

如何在列和其他变量中检索具有相同ID和相同值的两行。这是表“数据”

+---------+----------------+-------------+
| post_id | meta_key       | meta_value  |
+---------+----------------+-------------+
| 1000    | payment_method | visa        |
| 1000    | other          | sometext    |
| 1000    | order_total    | 65.00       |
| 1000    | etc            | sometext2   |
| 1001    | payment_method | bacs        |
| 1001    | other          | sometext    |
| 1001    | order_total    | 105.00      |
| 1001    | etc            | sometext2   |
| 1002    | payment_method | visa        |
| 1002    | other          | sometext    |
| 1002    | order_total    | 28.00       |
| 1002    | etc            | sometext2   |
| ...     | ...            | ...         |
+---------+----------------+-------------+

您会看到Payment_method的值稳定,而order_total却是可变的。

我尝试过:

  

SELECT *从'data'中的meta_key IN('payment_method',   'order_total')GROUP BY post_id,meta_key

输出

+---------+-----------------+------------+
| post_id | meta_key        | meta_value |
+---------+-----------------+------------+
| 1000    | payment_method  | visa       |
| 1000    | order_total     | 65.00      |
| 1001    | payment_method  | bacs       |
| 1001    | order_total     | 105.00     |
| 1002    | payment_method  | visa       |
| 1002    | order_total     | 28.00      |
| ...     | ...             | ...        |
+---------+-----------------+------------+

我只想通过post_id支付方式=签证及其相应的金额。

+---------+-----------------+------------+
| post_id | meta_key        | meta_value |
+---------+-----------------+------------+
| 1000    | payment_method  | visa       |
| 1000    | order_total     | 65.00      |
| 1002    | payment_method  | visa       |
| 1002    | order_total     | 28.00      |
| ...     | ...             | ...        |
+---------+-----------------+------------+

谢谢。

3 个答案:

答案 0 :(得分:2)

您遇到的“问题”是,相关的数据在不同的行上,这实际上使它们不相关。您需要将此表自身连接起来,或执行数据透视操作以使数据位于同一行

假设您想要的输出与您显示的完全相同:

SELECT * FROM data WHERE meta_key = 'payment_method' and meta_value = 'visa'

UNION ALL

SELECT a.* 
FROM data a
INNER JOIN data v 
ON
  v.meta_key = 'payment_method' and 
  v.meta_value = 'visa' and 
  a.meta_key = 'order_total' and 
  a.id = v.id

魔术在联合之后的第二个查询中发生-我们再次选择所有签证行(别名为v),就像在联合之前的查询一样,但是这次我们将其用作过滤器以限制order_total行(别名为a)。 v表仅包含签证ID,因此当重新加入ID时,它会将a表过滤为仅同一组签证ID。 a中的行仅是总计的行,我们仅选择a。*

就排除了所有v行信息。

此查询是一种更容易理解的替代形式:

SELECT * 
FROM data 
WHERE 
  meta_key in ('payment_method', 'order_total') and 
  ID in (SELECT x.id FROM data x WHERE x.meta_key = 'payment_method' and x.meta_value = 'visa')

实际上是同一件事;创建签证ID列表,然后将其用于将结果过滤为“仅那些ID”以及“仅付款方式和订单总行数”

如果您最终希望将数据放在同一行上,则最好使用以下方法立即将其旋转:

SELECT id, 'visa' as payment_method, max(case when meta_key = 'order_total' then meta_value end) as order_total
FROM data 
WHERE meta_key IN ('payment_method', 'order_total')
GROUP BY id 
HAVING max(case when meta_key = 'payment_method' then meta_value end) = 'visa'

答案 1 :(得分:1)

您可以使用旋转逻辑为每个键查找所需的值。别名为d2的子查询按帖子进行汇总,并且仅返回付款方式为Visa的帖子。然后,我们将您的原始data表加入此子查询,以仅限制您要查看的帖子。

SELECT
    d1.post_id,
    d1.meta_key,
    d1.meta_value
FROM data d1
INNER JOIN
(
    SELECT post_id
    FROM data
    GROUP BY post_id
    HAVING MAX(CASE WHEN meta_key = 'payment_method' THEN meta_value END) = 'visa'
) d2
    ON d1.post_id = d2.post_id
WHERE
    d1.meta_key IN ('payment_method', 'order_total')
ORDER BY
    d1.post_id,
    d1.meta_key DESC;

screen capture from demo

Demo

答案 2 :(得分:1)

您可以使用subquerygroup by

select post_id
    , meta_key
    , meta_value    
from data 
where post_id in 
    (select post_id 
    from data
    where meta_key in ('payment_method', 'order_total') and meta_value='visa'
    group by post_id
    having count(1) = 2)
order by post_id, meta_value desc