Reputation: 111
I have table in MySQL where I would like to get stats on finding usage limits of users for 3 cases
For the reason of feeding a control object I need these are three rows, so I started using MySQL UNION but I get strange results. Here is what I have
mysql> desc senderlimits;
+----------+--------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+-------------------+-------+
| authid | varchar(128) | NO | | NULL | |
| ip | varchar(40) | NO | | NULL | |
| cnt | int(11) | NO | | 1 | |
| datetime | timestamp | NO | | CURRENT_TIMESTAMP | |
+----------+--------------+------+-----+-------------------+-------+
4 rows in set (0.00 sec)
mysql> select count(distinct ip) as ipl from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 1 hour) UNION select sum(cnt) as cntl from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 24 hour) UNION select sum(cnt) as vcnt from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 10 minute) ;
+------+
| ipl |
+------+
| 1 |
| 95 |
+------+
2 rows in set (0.04 sec)
mysql> select count(distinct ip) as ipl from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 1 hour);
+-----+
| ipl |
+-----+
| 0 |
+-----+
1 row in set (0.01 sec)
mysql> select sum(cnt) as cntl from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 24 hour) ;
+------+
| cntl |
+------+
| 95 |
+------+
1 row in set (0.02 sec)
mysql> select count(authid) as vcnt from senderlimits where authid='[email protected]' and datetime > date_sub(now(),INTERVAL 10 minute);
+------+
| vcnt |
+------+
| 1 |
+------+
1 row in set (0.02 sec)
mysql>
The results are very strange when I use the UNION option. Does any expert know why? or how I can achieve the same result as 0 95 1
in that order?
Upvotes: 0
Views: 214
Reputation: 1269803
UNION
removes duplicates. You want UNION ALL
:
select count(distinct ip) as ipl
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 1 hour)
UNION ALL
select sum(cnt) as cntl
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 24 hour)
UNION ALL
select sum(cnt) as vcnt
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 10 minute) ;
However, you shouldn't depend on the ordering of the results being the same as the order of the subqueries (this is not guaranteed, even if it often happens in practice). You should include a column specifying which number means what:
select '1 hour' as which, count(distinct ip) as ipl
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 1 hour)
UNION ALL
select '24 hour' as which, sum(cnt) as cntl
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 24 hour)
UNION ALL
select '10 minutes' as which, sum(cnt) as vcnt
from senderlimits
where authid = '[email protected]' and datetime > date_sub(now(),INTERVAL 10 minute) ;
Upvotes: 1