This is my MySQL databse:
+-----+------------+----------+----------------+--------------+-----------------+
| id | data | hora | conexoes_total | conexoes_sim | conexoes_lentas |
+-----+------------+----------+----------------+--------------+-----------------+
| 1 | 2013-11-18 | 00:00:02 | 200 | 1 | 30 |
| 2 | 2013-11-18 | 10:15:03 | 14 | 2 | 25 |
| 3 | 2013-11-18 | 10:30:03 | 53 | 3 | 25 |
| 4 | 2013-11-18 | 10:45:02 | 60 | 5 | 26 |
| 5 | 2013-11-18 | 11:00:02 | 66 | 3 | 27 |
| 6 | 2013-11-18 | 11:15:03 | 74 | 5 | 27 |
.
.
.
I want select * from every 00:00:% data and the last value inserted..
I already know how to select the midnight values: SELECT * FROM audiencia WHERE hora LIKE '00:00:%';, and this what i got:
+-----+------------+----------+----------------+--------------+-----------------+
| id | data | hora | conexoes_total | conexoes_sim | conexoes_lentas |
+-----+------------+----------+----------------+--------------+-----------------+
| 1 | 2013-11-18 | 00:00:02 | 200 | 1 | 30 |
| 57 | 2013-11-19 | 00:00:02 | 446 | 1 | 97 |
| 153 | 2013-11-20 | 00:00:02 | 300 | 3 | 173 |
| 349 | 2013-11-21 | 00:00:02 | 42 | 2 | 94 |
+-----+------------+----------+----------------+--------------+-----------------+
But now i want to show the last value inserted in table together with the above result..
How can i manage a command to do that to me?
(SELECT * FROM audiencia WHERE hora LIKE '00:00:%')
UNION
(SELECT * FROM audiencia ORDER BY id DESC LIMIT 1);
Do you want to fetch the last value inserted for column hora of table audiencia which starts from 00:00: ?
If Answer to the above question is YES, then the below SQL will solve your problem.
SELECT * FROM audiencia WHERE hora LIKE '00:00:%' ORDER BY id DESC LIMIT 1;
In case the answer to the above question is NO, then I might have not understood the requirement properly. Kindly, please explain the requirement.
Thanks,
Abhijit
Related
I have a problem in which I have a STUDENT table as
+-------------+-------------+-------------+-------------+---------------+
| roll_number | name | subject_one | subject_two | subject_three |
+-------------+-------------+-------------+-------------+---------------+
| 1 | Sheila | 32 | 48 | 64 |
| 2 | Rachel | 24 | 21 | 25 |
| 3 | Christopher | 55 | 12 | 10 |
+-------------+-------------+-------------+-------------+---------------+
I want the print the output as
+-------------+-------------+-------------+
| roll_number | name | total |
+-------------+-------------+-------------+
| 1 | Sheila | 144|
| 2 | Rachel | 70 |
| 3 | Christopher | 77 |
+-------------+-------------+-------------+
and select all student having marks greater than 75 ??
How can I achieve this using MYSQL ??
I think you just need the aggregate functions and using them is enough. I am not sure if it can help you or not.
SELECT roll_number , name , (subject_one + subject_two + subject_three) AS total FROM STUDENT HAVING total > 75 ;
I have a table like this:
mysql> select * from studentscore;
+------------+-----------+-------+
| student_id | cource_id | score |
+------------+-----------+-------+
| 1 | 1 | 80 |
| 1 | 2 | 90 |
| 1 | 3 | 85 |
| 1 | 4 | 78 |
| 2 | 2 | 53 |
| 2 | 3 | 77 |
| 2 | 5 | 80 |
| 3 | 1 | 71 |
| 3 | 2 | 70 |
| 3 | 4 | 80 |
| 3 | 5 | 65 |
| 3 | 6 | 75 |
| 4 | 2 | 90 |
| 4 | 3 | 80 |
| 4 | 4 | 70 |
| 4 | 6 | 95 |
| 5 | 1 | 60 |
| 5 | 2 | 70 |
| 5 | 5 | 80 |
| 5 | 6 | 69 |
| 6 | 1 | 76 |
| 6 | 2 | 88 |
| 6 | 3 | 87 |
| 7 | 4 | 80 |
| 8 | 2 | 71 |
| 8 | 3 | 58 |
| 8 | 5 | 68 |
| 9 | 2 | 88 |
| 10 | 1 | 77 |
| 10 | 2 | 76 |
| 10 | 3 | 80 |
| 10 | 4 | 85 |
| 10 | 5 | 83 |
| 11 | 3 | 80 |
| 12 | 4 | 99 |
| 13 | 5 | 74 |
+------------+-----------+-------+
I want to show student_id and students' average scores that are higher than 80.
The output I want is like this:
+------------+-------------------+
| student_id | Average |
+------------+-------------------+
| 1 | 83.25 |
| 4 | 83.75 |
| 6 | 83.66666666666667 | // and how can I make this result shorter like 83.67?
| 7 | 80 |
| 9 | 88 |
| 10 | 80.2 |
| 11 | 80 |
| 12 | 99 |
+------------+-------------------+
I've tried the following codes
mysql> select student_id, avg(score) as average_score
-> from studentscore
-> group by student_id
-> where avg(score) >= 80;
and it gave me an syntax error.
I know by rules the where clause should go before the group by clause but I can't because the where clause depends on the result from the group by clause, and if I switch their position it will give me another error("Invalid use of group function").
Can some one tell me how to get the table I want?
use "having" instead of "where"
use having instead of where.
Here's the difference:
with where you can write a predicate that will be applied to each row
with having you can write a predicate that will applied to each group
and in your case, the 2nd is the only solution that can work.
select student_id, avg(score) as average_score
from studentscore
group by student_id
having avg(score) >= 80;
where applies a filter to your data before grouping has taken place, whereas having applies a filter post-grouping. round(,2) will format as you also ask:
select student_id, round(avg(score), 2) as average_score
from studentscore
group by student_id
having average_score >= 80;
Given the table below I want to select the rows for which the same 'CODE' is associated with multiple 'SUB_CODE'.
+------+------------+-------------+
| DIV | CODE | SUB_CODE |
+------+------------+-------------+
| 11 | 1000 | 1212 |
| 11 | 1000 | 1213 |
| 11 | 1000 | 3434 |
| 11 | 1000 | 1000 |
| 11 | 1000 | 3000 |
| 11 | 3000 | 1213 |
| 11 | 2000 | 1212 |
| 20 | 1500 | 5656 |
| 20 | 1500 | 1213 |
+------+------------+-------------+
For the above table the result should be
+------+------------+-------------+
| DIV | CODE | SUB_CODE |
+------+------------+-------------+
| 11 | 1000 | 1212 |
| 11 | 1000 | 1213 |
| 11 | 1000 | 3434 |
| 11 | 1000 | 1000 |
| 11 | 1000 | 3000 |
| 11 | 1500 | 5656 |
| 11 | 1500 | 1213 |
+------+------------+-------------+
This is what I tried, how ever my results fails.
Select CODE from TABLE_NAME where (count(SUB_CODE) > 1);
First fetch the CODEs for which multiple SUB_CODEs exists; then project the table columns filtering using the above results as a nested query:
select * from TABLE_NAME where CODE in
(select CODE from TABLE_NAME group by CODE having count(SUB_CODE) > 1);
demo: http://sqlfiddle.com/#!9/1d91f/3/0
TRY THIS:
Select `DIV`, `CODE`, `SUB_CODE` from TABLE_NAME GROUP BY `SUB_CODE`
I don't know if this is something I can achieve effectively with sub queries, or how to even build a query for this. I have to extract some knowledge about people no longer using our system. Imagine we have 3 users with user id 1024, 1234, and 5678; and User 1024 and 1234 are using theme A, and 5678 is using theme B:
$ SELECT * FROM user; | $ SELECT * FROM user_theme;
+------+------+ | +------+-------+
| id | name | | | user | theme |
+------+------+ | +------+-------+
| 1024 | John | | | 1024 | A |
| 1234 | Jane | | | 1234 | A |
| 5678 | Jeff | | | 5678 | B |
+------+------+ | +------+-------+
The usage tracking table appears as this:
$ SELECT * FROM user_usage;
+----+------+---------------------+------+
| id | user | date | uses |
+----+------+---------------------+------+
| 1 | 1234 | 2014-08-02 00:00:00 | 5 |
| 2 | 1234 | 2014-08-03 00:00:00 | 5 |
| 3 | 1234 | 2014-08-04 00:00:00 | 3 |
| 4 | 1234 | 2014-08-05 00:00:00 | 6 |
| 5 | 1024 | 2014-08-02 00:00:00 | 8 |
| 6 | 1024 | 2014-08-03 00:00:00 | 7 |
| 7 | 1024 | 2014-08-04 00:00:00 | 4 |
| 8 | 1024 | 2014-08-05 00:00:00 | 6 |
| 9 | 1024 | 2014-09-02 00:00:00 | 1 |
| 10 | 1024 | 2014-09-03 00:00:00 | 2 |
| 11 | 1024 | 2014-09-04 00:00:00 | 3 |
| 12 | 1024 | 2014-09-05 00:00:00 | 4 |
| 13 | 5678 | 2014-08-02 00:00:00 | 8 |
| 14 | 5678 | 2014-08-03 00:00:00 | 7 |
| 15 | 5678 | 2014-08-04 00:00:00 | 4 |
| 16 | 5678 | 2014-08-05 00:00:00 | 6 |
| 17 | 5678 | 2014-09-02 00:00:00 | 1 |
| 18 | 5678 | 2014-09-03 00:00:00 | 2 |
| 19 | 5678 | 2014-09-04 00:00:00 | 3 |
| 20 | 5678 | 2014-09-05 00:00:00 | 4 |
+----+------+---------------------+------+
I want to find out the break down to see how many usage have dropped from our system in 2014-09 (aka: have usage data in 2014-08, but no longer in 2014-09), grouped by the theme. So I want to write something like:
SELECT
user_theme.theme,
SUM(user_usage.users) 'uses lost'
FROM
user_theme
LEFT JOIN user_usage
ON user_theme.user = user_usage.user
WHERE
...
GROUP BY
user_theme.theme
# HAVING ...?
And get result such as:
+-------+-----------+
| theme | uses lost |
+-------+-----------+
| A | 19 |
| B | 0 |
+-------+-----------+
Where the 19 comes from SUM(uses) for WHERE user = 1234 AND YEAR(date) = 2014 AND MONTH(date) = 8.
I don't know I care about the SUM(uses) from user = 1234 in advance, because I only know I need to include user 1234 in the SUM(uses)'s WHERE clause because SUM(uses) for WHERE user = 1234 AND YEAR(date) = 2014 AND MONTH(date) = 9 is 0.
There's actually a lot of users, and a handful of themes (around 20K users, and about 10 themes), so ideally, I think I'd like to avoid doing the filtering in code as opposed to directly in the database. Is there a way to do this effectively in MySQL using raw SQL queries?
Here is query which compares current month with previous one:
set #current_month = now();
set #previous_month = date_sub(#current_month, interval 1 month);
set #current_month = concat(year(#current_month), month(#current_month));
set #previous_month = concat(year(#previous_month), month(#previous_month));
select a.`theme`, sum(ifnull(b.uses_lost,0)) as uses_lost
from
`user_theme` as a
left outer join
(
select `user`, sum(uses) as uses_lost
from `user_usage`
where concat(year(`date`), month(`date`)) = #previous_month
and `user` not in (
select `user`
from `user_usage`
where concat(year(`date`), month(`date`)) = #current_month)
group by `user`
) as b
on (a.`user`=b.`user`)
group by a.`theme`;
fiddle for play
main idea is to find all users who used system during last month and has no rows during current month
Using MySQL 5.5.30, for a table, purchase_order_product (MyISAM), that has the following records:
+----------+------------------+
| order_id | order_product_id |
+----------+------------------+
| 98 | 1 |
| 99 | 14 |
| 99 | 15 |
| 100 | 16 |
| 100 | 17 |
| 100 | 18 |
| 101 | 19 |
| 102 | 20 |
+----------+------------------+
When I run the following query from MySQL Workbench 5.2.47 CE:
SELECT pop.order_id, pop.order_product_id,
#RUNNING:=IF(#PREVIOUS = pop.order_id, #RUNNING, 0) + 1 AS rownum,
#PREVIOUS:=pop.order_id as previd
FROM purchase_order_product pop
ORDER BY pop.order_id , pop.order_product_id ASC;
I get the following output:
+----------+------------------+--------+--------+
| order_id | order_product_id | rownum | previd |
+----------+------------------+--------+--------+
| 98 | 1 | 1 | 98 |
| 99 | 14 | 1 | 99 |
| 99 | 15 | 2 | 99 |
| 100 | 16 | 1 | 100 |
| 100 | 17 | 2 | 100 |
| 100 | 18 | 3 | 100 |
| 101 | 19 | 1 | 101 |
| 102 | 20 | 1 | 102 |
+----------+------------------+--------+--------+
My desired goal is the value of rownum, which is fine and as expected so far...
HOWEVER, when I run the query from within my PHP code OR from the mysql command line against the same database using the same db user, I get the following output:
+----------+------------------+--------+--------+
| order_id | order_product_id | rownum | previd |
+----------+------------------+--------+--------+
| 98 | 1 | 1 | 98 |
| 99 | 14 | 1 | 99 |
| 99 | 15 | 1 | 99 |
| 100 | 16 | 1 | 100 |
| 100 | 17 | 1 | 100 |
| 100 | 18 | 1 | 100 |
| 101 | 19 | 1 | 101 |
| 102 | 20 | 1 | 102 |
+----------+------------------+--------+--------+
As you can see, rownum is always 1!
I have search extensively for a solution to this perplexing issue, to no avail. Does anyone have any idea what may be going on? Am I doing something wrong?
You need to initialize the variable:
SET #RUNNING:=0;
SET #PREVIOUS:=0;
This must be done before your query and in the same mysql session.