Converting subselects to joins, part 2
This commit is contained in:
35
2011-11-29-converting-subselects-to-joins-part-2.html
Normal file
35
2011-11-29-converting-subselects-to-joins-part-2.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!--# set var="title" value="Converting subselects to joins, part 2" -->
|
||||||
|
<!--# set var="date" value="November 29, 2011" -->
|
||||||
|
|
||||||
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
|
<p><a href="2011-07-12-converting-subselects-to-joins.html">I previously discussed this in depth</a>. However, today I saw a case that I didn't cover:</p>
|
||||||
|
|
||||||
|
<p>You have a table of Users and a table of Logins, with a row for each user login event. You're looking for users that have logged in within the last 31 days. The initial version of this I saw used a derived table:</p>
|
||||||
|
|
||||||
|
<pre><code>SELECT
|
||||||
|
UserId,
|
||||||
|
LastLogin
|
||||||
|
FROM Users
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
UserId,
|
||||||
|
DATEDIFF(NOW(), MAX(TimeStamp)) AS LastLogin
|
||||||
|
FROM Logins
|
||||||
|
GROUP BY UserId
|
||||||
|
) AS Temp USING (UserId)
|
||||||
|
WHERE LastLogin &lt;= 31;
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>We can convert this to a simple JOIN with the magic of HAVING. HAVING is like WHERE, but applies after aggregation:</p>
|
||||||
|
|
||||||
|
<pre><code>SELECT
|
||||||
|
UserId,
|
||||||
|
DATEDIFF(NOW(), MAX(TimeStamp)) AS LastLogin
|
||||||
|
FROM Users
|
||||||
|
JOIN Logins USING (UserId)
|
||||||
|
GROUP BY UserId
|
||||||
|
HAVING LastLogin &lt;= 31;
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<!--# include file="include/bottom.html" -->
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
<li>2016-Feb-15: <a href="2016-02-15-cable-modem-channel-party.html">Cable modem channel party</a></li>
|
<li>2016-Feb-15: <a href="2016-02-15-cable-modem-channel-party.html">Cable modem channel party</a></li>
|
||||||
<li>2016-Feb-01: <a href="2016-02-01-how-to-enrage-your-cable-modem.html">How to enrage your cable modem</a></li>
|
<li>2016-Feb-01: <a href="2016-02-01-how-to-enrage-your-cable-modem.html">How to enrage your cable modem</a></li>
|
||||||
<li>2016-Feb-01: <a href="2016-02-01-hall-of-2-4-ghz-shame-2016-edition.html">Hall of 2.4 GHz Shame, 2016 Edition</a></li>
|
<li>2016-Feb-01: <a href="2016-02-01-hall-of-2-4-ghz-shame-2016-edition.html">Hall of 2.4 GHz Shame, 2016 Edition</a></li>
|
||||||
|
<li>2011-Nov-29: <a href="2011-11-29-converting-subselects-to-joins-part-2.html">Converting subselects to joins, part 2</a></li>
|
||||||
<li>2011-Nov-29: <a href="2011-11-29-safer-data-changes.html">Safe(r) data changes</a></li>
|
<li>2011-Nov-29: <a href="2011-11-29-safer-data-changes.html">Safe(r) data changes</a></li>
|
||||||
<li>2011-Aug-09: <a href="2011-08-09-innodb-as-the-default-table-type.html">InnoDB as the default table type</a></li>
|
<li>2011-Aug-09: <a href="2011-08-09-innodb-as-the-default-table-type.html">InnoDB as the default table type</a></li>
|
||||||
<li>2011-Aug-08: <a href="2011-08-08-database-best-practices-for-future-scalability.html">Database best practices for future scalability</a></li>
|
<li>2011-Aug-08: <a href="2011-08-08-database-best-practices-for-future-scalability.html">Database best practices for future scalability</a></li>
|
||||||
|
|||||||
33
markdown/2011-11-29-converting-subselects-to-joins-part-2.md
Normal file
33
markdown/2011-11-29-converting-subselects-to-joins-part-2.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!--# set var="title" value="Converting subselects to joins, part 2" -->
|
||||||
|
<!--# set var="date" value="November 29, 2011" -->
|
||||||
|
|
||||||
|
<!--# include file="include/top.html" -->
|
||||||
|
|
||||||
|
[I previously discussed this in depth](2011-07-12-converting-subselects-to-joins.html). However, today I saw a case that I didn't cover:
|
||||||
|
|
||||||
|
You have a table of Users and a table of Logins, with a row for each user login event. You're looking for users that have logged in within the last 31 days. The initial version of this I saw used a derived table:
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
UserId,
|
||||||
|
LastLogin
|
||||||
|
FROM Users
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
UserId,
|
||||||
|
DATEDIFF(NOW(), MAX(TimeStamp)) AS LastLogin
|
||||||
|
FROM Logins
|
||||||
|
GROUP BY UserId
|
||||||
|
) AS Temp USING (UserId)
|
||||||
|
WHERE LastLogin <= 31;
|
||||||
|
|
||||||
|
We can convert this to a simple JOIN with the magic of HAVING. HAVING is like WHERE, but applies after aggregation:
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
UserId,
|
||||||
|
DATEDIFF(NOW(), MAX(TimeStamp)) AS LastLogin
|
||||||
|
FROM Users
|
||||||
|
JOIN Logins USING (UserId)
|
||||||
|
GROUP BY UserId
|
||||||
|
HAVING LastLogin <= 31;
|
||||||
|
|
||||||
|
<!--# include file="include/bottom.html" -->
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
1. 2016-Feb-15: [Cable modem channel party](2016-02-15-cable-modem-channel-party.html)
|
1. 2016-Feb-15: [Cable modem channel party](2016-02-15-cable-modem-channel-party.html)
|
||||||
1. 2016-Feb-01: [How to enrage your cable modem](2016-02-01-how-to-enrage-your-cable-modem.html)
|
1. 2016-Feb-01: [How to enrage your cable modem](2016-02-01-how-to-enrage-your-cable-modem.html)
|
||||||
1. 2016-Feb-01: [Hall of 2.4 GHz Shame, 2016 Edition](2016-02-01-hall-of-2-4-ghz-shame-2016-edition.html)
|
1. 2016-Feb-01: [Hall of 2.4 GHz Shame, 2016 Edition](2016-02-01-hall-of-2-4-ghz-shame-2016-edition.html)
|
||||||
|
1. 2011-Nov-29: [Converting subselects to joins, part 2](2011-11-29-converting-subselects-to-joins-part-2.html)
|
||||||
1. 2011-Nov-29: [Safe(r) data changes](2011-11-29-safer-data-changes.html)
|
1. 2011-Nov-29: [Safe(r) data changes](2011-11-29-safer-data-changes.html)
|
||||||
1. 2011-Aug-09: [InnoDB as the default table type](2011-08-09-innodb-as-the-default-table-type.html)
|
1. 2011-Aug-09: [InnoDB as the default table type](2011-08-09-innodb-as-the-default-table-type.html)
|
||||||
1. 2011-Aug-08: [Database best practices for future scalability](2011-08-08-database-best-practices-for-future-scalability.html)
|
1. 2011-Aug-08: [Database best practices for future scalability](2011-08-08-database-best-practices-for-future-scalability.html)
|
||||||
|
|||||||
Reference in New Issue
Block a user