自我加入或替代中的MySQL子查询?

时间:2015-04-23 17:06:14

标签: mysql subquery self-join

我试图为我们的奖学金筹款俱乐部提出一个查询,该俱乐部将所有门票销售归还给晚宴活动,并指出每个购买门票的会员是否是最新的会费(在过去365天内付款)。这将用于登录表,指示已购买了多少票,以及我们是否需要让他们续订其会员资格,更新他们的联系信息等。我可以返回门票销售或活跃会员资格,但我无法确定如何将两个查询合并到一个查询中,因此我不必使用PHP数组。希望有人可以提供帮助:

/ *以下是相关表格* /

的摘录
+----------+  +--------------------+  +--------------------------+
| members  |  | store_transactions |  | store_product_categories |
+----------+  +--------------------+  +--------------------------+
| id       |  | id                 |  | id                       |
| last     |  | invoice            |  | category                 |
| first    |  | memberID           |  | officeID                 |
| spouse   |  | categoryID         |  | modified                 |
| lifetime |  | productID          |  +--------------------------+
| email    |  | name               |  
| phone    |  | price              |  +-------------+
| created  |  | quantity           |  | pmt_methods |
+----------+  | addedBy            |  +-------------+
              | pmtMethod          |  | id          |
              | created            |  | method      |
              +--------------------+  +-------------+

/ *第一个查询返回所有添加的Muster门票销售(通过网站自动交易或通过俱乐部官员手动)和pmt方法(仅限RSVP,现金等)* /

SELECT member.last, member.first, member.spouse,  
       member.email, member.phone, 
       SUM(transaction.quantity) dinnerTix, 
       SUM(transaction.price * transaction.quantity) total, 
       IF (addedBy = '0' OR addedBy IS NULL, 'Website', 
           CONCAT_WS(' ', officer.first, officer.last)) 
           AS addedBy, method
FROM store_transactions AS transaction
LEFT JOIN members AS member ON transaction.memberID = member.id
LEFT JOIN store_product_categories ON transaction.categoryID =   
          store_product_categories.id 
LEFT JOIN pmt_methods ON transaction.pmtMethod = pmt_methods.id
LEFT JOIN members officer ON officer.id = addedBy
WHERE categoryID = '2' 
    AND year(transaction.created) = '2015' 
    AND (name LIKE '%member%') 
GROUP BY CONCAT(member.last, '_', member.first)
ORDER BY member.last, member.first;

第一个查询返回如下内容:

+------+-------+--------+-------------+--------------+---
| last | first | spouse | email       | phone        |
+------+-------+--------+-------------+--------------+---
|  Doe | John  | Jane   | abc@abc.com | 123-456-7890 |
+------+-------+--------+-------------+--------------+---

---+-----------+--------+-----------+--------+
   | dinnerTix | total  | addedBy   | method |
---+-----------+--------+-----------+--------+
   |     5     | 150.00 | President | cash   |
---+-----------+--------+-----------+--------+

/ *此第二个查询返回所有活跃成员,添加1年到最后一次会员购买以显示年度会员到期* /

SELECT last, first,
    DATE_FORMAT(ADDDATE(store_transactions.created, INTERVAL 1 YEAR), 
        '%M %e, %Y') AS expires
FROM store_transactions
LEFT JOIN members ON store_transactions.memberID = members.id
WHERE store_transactions.created >= SUBDATE(CURDATE(), INTERVAL 1     
    YEAR) AND categoryID = 1 OR lifetime = 'Y'
GROUP BY members.id
ORDER BY members.last, members.first;

第二个查询返回如下内容:

+------+-------+-------------+
| last | first | expires     |
+------+-------+-------------+
|  Doe | John  | May 3, 2015 |
+------+-------+-------------+

我认为将两个查询组合起来很简单,因此第二个查询中返回的到期日期将附加到第一个查询结果的每一行。不幸的是,我在这里追逐我的尾巴,所以任何帮助都将不胜感激!这是我第一次尝试自我加入和表别名,所以我试图扩大我的视野而不破坏过去8年来一直运行良好的网站!谢谢!

1 个答案:

答案 0 :(得分:1)

应该很容易。让我们说Q1 =您的第一个查询,Q2 =您的第二个查询。它应该简单:

select q1.*, q2.expires
  from (Q1) q1
    inner join (Q2) q2
      on q1.last = q2.last and q1.first = q2.first

只需将Q1所在的第一个查询复制并粘贴到括号内,然后对第二个查询执行相同操作Q2

当然,如果有两个人姓名相同,这将会中断,在这种情况下,最好在两个查询中包含id字段,然后加入。