为匹配和不匹配创建SQL查询

时间:2013-11-10 03:07:32

标签: sql

我在SQL查询中涉及3个表,我试图弄清楚如何编写。

itemmeta

order_item_id       meta_key            meta_value
------------------- ------------------  -------------------
1                   _subscription_test  0
1                   _subscription_more  0
1                   _product_id         100
2                   _subscription_test  0
2                   _subscription_more  0
2                   _product_id         100
3                   _product_id         100

order_items

order_item_id       order_id
------------------- ------------------
1                   200
2                   201
3                   202

postmeta *

order_id            meta_key
------------------  ------------------
200                 _original_order

查询应执行以下操作:

  1. 查找itemmeta.order_item_id

    Where itemmeta.meta_key LIKE '_subscription%' 
       OR itemmeta.meta_key LIKE '_recurring%'
    

    - >仅使用此处的唯一值

  2. 获取那些itemmeta.order_item_id值并匹配到order_items.order_item_id
    - > return order_items.order_id

  3. 将那些order_items.order_id与postmeta.post_id匹配,其中postmeta.meta_key与'_original_order'不匹配
    (扔掉存在元密钥的任何order_ids)

  4. 那些结果,引用回itemmeta.order_item_id并找到itemmeta.meta_key ='_ product_id'的那些 - > return itemmeta.meta_value

  5. 最终结果:

    order_items.order_id, order_itemmeta.meta_value (_product_id)
    

    所以在上面的表中,这将返回1行:

      order_id => 201
      meta_value => 100
    

    我不太确定执行此查询所需的合并和否定。非常感谢有人可能提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

也许这样的事情可行吗?

SELECT order_id, meta_value FROM 
(
  SELECT oi.order_id, oi.order_item_id FROM order_items oi
  LEFT JOIN postmeta pm ON oi.order_id = pm.order_id
  WHERE oi.order_item_id IN (SELECT im.order_item_id FROM itemmeta im WHERE im.meta_key LIKE '_subscription%' OR im.meta_key LIKE '_recurring%')
  AND oi.order_id NOT IN (SELECT pm.order_id FROM postmeta pm WHERE pm.meta_key = '_original_order')
) subquery 
INNER JOIN itemmeta im ON subquery.order_item_id = im.order_item_id
WHERE im.meta_key = '_product_id'

使用此SQL Fiddle进行测试时,会得出以下结果:

ORDER_ID    META_VALUE
201         100

我早上很早就在那里,我显然没有经过彻底的测试,所以没有保证;)

答案 1 :(得分:1)

可能的解决方案

SELECT i.order_id, m.meta_value
  FROM
(
  SELECT order_item_id,
         MAX(CASE WHEN meta_key = '_product_id' THEN meta_value END) meta_value
    FROM itemmeta
   WHERE meta_key LIKE '_subscription%' 
      OR meta_key LIKE '_recurring%'
      OR meta_key = '_product_id'
   GROUP BY order_item_id
  HAVING MAX(meta_key LIKE '_subscription%')
       + MAX(meta_key LIKE '_recurring%') > 0
) m JOIN order_items i 
    ON m.order_item_id = i.order_item_id LEFT JOIN postmeta p 
    ON i.order_id = p.order_id 
   AND p.meta_key = '_original_order'
 WHERE p.order_id IS NULL

输出:

| ORDER_ID | META_VALUE |
|----------|------------|
|      201 |        100 |

这是 SQLFiddle 演示