简体   繁体   中英

MySQL subquery within self join or alternative?

I'm trying to form a query for our scholarship fundraising club that returns all ticket sales to a dinner event, as well as indicates whether or not each member who's purchased tickets is current on her dues (paid within last 365 days). This will be used for a sign-in sheet that indicates how many tickets have been purchased and whether we need to ask them to renew their membership yet, update their contact info, etc. I can return either ticket sales or active memberships, but I can't figure how to incorporate both queries into a single query so I won't have to use a PHP array. Hopefully someone can help:

/* Here are excerpts from the relevant tables */

+----------+  +--------------------+  +--------------------------+
| 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      |
              +--------------------+  +-------------+

/* The 1st query returns all Muster ticket sales w/whom added (auto transaction via website or manual via club officer) and method of pmt (RSVP only, cash, etc) */

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;

The 1st query returns something like this:

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

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

/* This 2nd query returns all active members, adding 1 year to last membership purchase to show annual membership expiration */

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;

The 2nd query returns something like this:

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

I thought it would be simple to combine the two queries so the expiration date returned in the second query would be appended to each row of the first query result. Unfortunately, I'm chasing my tail here, so any help would be greatly appreciated! This was my first foray into self-joins and table aliases, so I'm trying to expand my horizons without breaking the site which has been operating smoothly for the last 8 years! Thanks!!

It should be easy. Lets say Q1 = your first query, and Q2 = your second query. it should be as simple as:

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

Simply copy and paste your first query where Q1 is, inside the parenthesis, and do the same for your second query into Q2

Of course, this will break if there are two people with the same name, in which case you would be better off including the id field in both queries, and joining on that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM