Hide first row in database query - mysql

I have a query that exports its results via email in a table format, i would really like to hide the first row of my data so it never gets exported with my results.
Example database table:
+------+--------+--------+
|Number|Language|Date |
+------+--------+--------+
|2039 |text 1 |20/01/14|
+------+--------+--------+
|1 |text 2 |20/01/14|
+------+--------+--------+
|2 |text 3 |20/01/14|
+------+--------+--------+
The query that i am using at the moment is :
SELECT
COUNT(*) as `count`, `lang`, DATE(NOW()) as `week_ending`
FROM
mydata.table
WHERE
`date` > DATE_ADD(DATE(NOW()), INTERVAL - 1 WEEK) AND
`date` < DATE(NOW())
GROUP BY `lang` , DATE(NOW());
Is it possible to hide the row 2039 text 1 20/01/14

SELECT COUNT(*) as `count`,`lang`, DATE(NOW()) as `week_ending` FROM mydata.table WHERE `date` > DATE_ADD(DATE(NOW()), INTERVAL -1 WEEK) AND `date` < DATE(NOW()) GROUP BY `lang`, DATE(NOW()) LIMIT 1,x;
replace x with a number big enough to contain all your records.
or use, instead of x, 18446744073709551615, that is maximum value of big INT unsigned.

It really depends on which row you think appears first depending on the order. If no order is specified, you usually get your records based on insertion order.
If you are ordering by Number column in descending then add where clause
WHERE Number < MAX(Number)
If you are ordering by Number in ascending then add where clause
WHERE Number > MIN(Number)

Use LIMIT 1, N at the End of query.
Where N is the number of rows you want to retrieve.

if 'number' is the primary key you can get the same result using following query also.
SELECT
COUNT(*) as 'count', t1.language, DATE(NOW()) as 'week_ending'
FROM
(select * from 'mydata.table') t1 left join
(select * from 'mydata.table' limit 1) t2 on t1.number = t2.number
where t2.number is null
And
t1.date > DATE_ADD(DATE(NOW()), INTERVAL - 1 WEEK)
AND t1.date < DATE(NOW())
GROUP BY t1.language , DATE(NOW());

Related

Show number of lower and higher values in SQL

I have a certain problem while trying to make an SQL. I have a table with the following format and data.
id
value
date
12
3
2020-06-01
12
4
2020-06-09
12
1
2020-06-20
5
4
2020-06-11
5
5
2020-06-17
My goal is to make something like that:
id
lower
higher
12
1
1
5
0
1
This looks for the value of the oldest row IN specific interval (ex. 100 days)and it compares it with all dates after that if their values are higher and lower and return the count.
I do have something that works but it requires more queries:
One to group take all ids with dates in the interval of xx days
SELECT id FROM table
WHERE date >= CURDATE() - INTERVAL 30 DAY GROUP BY id
ORDER BY id ASC;
And then I loop through each row and get its lower and higher values.
SELECT
*
FROM
(
SELECT
COUNT(*) AS higher, id
FROM
`table`
WHERE
id = 12 AND date > CURDATE() - INTERVAL 30 DAY AND value > (
SELECT value FROM table
WHERE table.date >= CURDATE() - INTERVAL 30 DAY AND id = 12
ORDER BY `table`.`date` ASC LIMIT 1
)
) AS t1,(
SELECT
COUNT(*) AS deteriorated_placements
FROM
`table`
WHERE
id = 12 AND date > CURDATE() - INTERVAL 30 DAY AND value < (
SELECT value FROM table
WHERE table.date >= CURDATE() - INTERVAL 30 DAY AND id = 12
ORDER BY `table`.`date` ASC LIMIT 1
)
) AS t2;
The problem with that is that I do around 40 more queries. I know it maybe is not a big issue but
Is there a way to somehow combine those 2 queries?
Use first_value():
select id,
sum(value < value_1) as lower,
sum(value > value_1) as higher
from (select t.*,
first_value(value) over (partition by id order by date) as value_1
from t
) t
group by id;

Getting all previous records of table by date MySQL

My table currently has 21000 records, it's daily updated and almost 300 entries are inserted. Now, what I want is to have a query which will fetch the counts of elements that my table had for the previous 10 days, so it returns:
26000
21300
21000
etc
Right now, I wrote this:
"SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01'"
And it returns 21000 but only for 1 day. I want by query to return records according to 10 days.
However, this does it for only 1 day.
edit : database flavor is mysql and date column is date not datetime
The most efficient method may be aggregation and cumulative sums:
select date(task_start_time) as dte, count(*) as cnt_on_day,
sum(count(*)) over (order by date(task_start_time)) as running_cnt
from tbl_task
group by dte
order by dte desc
limit 10;
This returns the last 10 days in the data. You can easily adjust to more days if you like -- in fact all of them -- without much trouble.
I don't know if I'm wrong, but could you not simple add a GROUP BY - statement? Like:
"SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01' GROUP
BY task_start_time"
EDIT:
This should only work if task_start_time is a date, not if it is a datetime
EDIT2:
If it is a datetime you could use the date function:
SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01' GROUP
BY DATE(task_start_time)
You can use UNION ALL and date arithmetic.
SELECT count(*)
FROM tbl_task
WHERE task_start_time < current_date
UNION ALL
SELECT count(*)
FROM tbl_task
WHERE task_start_time < date_sub(current_date, INTERVAL 1 DAY)
...
UNION ALL
SELECT count(*)
FROM tbl_task
WHERE task_start_time < date_sub(current_date, INTERVAL 9 DAY);
Edit:
You might also join a derived table that uses FROM-less SELECTs and UNION ALL to get the days to look back and then aggregate. This might be a little easier to construct dynamically. (But it may be slower I suspect.)
SELECT count(*)
FROM (SELECT 0 x
UNION ALL
SELECT 1
...
UNION ALL
SELECT 9)
INNER JOIN tbl_task t
ON t.task_start_time < date_sub(current_date, INTERVAL x.x DAY)
GROUP BY x.x;
In MySQL version 8+ you can even use a recursive CTE to construct the table with the days.
WITH RECURSIVE x
AS
(
SELECT 0 x
UNION ALL
SELECT x + 1
FROM x
WHERE x + 1 < 10
)
SELECT count(*)
FROM x
INNER JOIN tbl_task t
ON t.task_start_time < date_sub(current_date, INTERVAL x.x DAY)
GROUP BY x.x;

Aggregate data by last n days for each row in MySQL

I have data in below format -
Date Amount
1/1/2000 1
2/1/2000 1
3/1/2000 1
4/1/2000 2
5/1/2000 1
6/1/2000 1
7/1/2000 1
Here, each row represents Amount collected on that day, I want to prepare a table where each row represents amount collected on last 3 days. Thus for 3/1/2000 - it will show amount =3 ( Amount 1 on 1/1 , 1 on 2/1 and 1 on 3/1 , so 1+1+1 = 3
So, from above data, table I want is -
Date Amount
1/1/2000 1 //1
2/1/2000 2 //1+1
3/1/2000 3 //1+1+1
4/1/2000 4 //1+1+2
5/1/2000 4 //1+2+1
6/1/2000 4 //2+1+1
7/1/2000 3 //1+1+1
How to write a SQL query for this?
I tried this -
select date, sum(amount) as amount_sum
from SQLTABLE
where DATEDIFF(date,date)<=2
group by date
You can use correlated subqueries in order to get the Amount values of the two previous records:
SELECT `Date`,
Amount +
COALESCE((SELECT Amount
FROM mytable AS t2
WHERE t2.`Date` < t1.`Date`
ORDER BY `Date` DESC LIMIT 1), 0) +
COALESCE((SELECT Amount
FROM mytable AS t2
WHERE t2.`Date` < t1.`Date`
ORDER BY `Date` DESC LIMIT 1, 1), 0) AS Amount
FROM mytable AS t1
The above query works even if there are gaps between consecutive records.
Edit:
If there are no gaps between consecutive records, then you can use the following query:
SELECT `Date`,
COALESCE((SELECT SUM(Amount)
FROM mytable AS t2
WHERE t2.date <= t1.date AND DATEDIFF(t1.date,t2.date) <= 2
ORDER BY `Date` DESC LIMIT 1), 0) AS Amount
FROM mytable AS t1
This can be done by using a sub-select.
SELECT date,
(SELECT sum(amount)
from SQLTABLE t2
WHERE DATEDIFF(t1.date,t2.date) IN (0,1,2)) amount_sum
from SQLTABLE t1

MySQL COUNT for days

I want to get the value of users visiting my page for 10 days in a chart. I need to COUNT() all the values from the last ten days.
The best layout would be
Day|COUNT(ip)
1 - 10
2 - 12
3 - 52
......
I hope you understand what I mean.
Can MySQL do this directly or need I to do this in PHP in 10 seperate querys?
Regards,
Moritz
Update with Tablestructure:
Id (Auto Increment)|Time (Unix Timestamp)|Ip|Referer
This should run fast for you
SELECT COUNT(ip) ipcount,dt FROM
(
SELECT ip,DATE(FROM_UNIXTIME(`Time`)) as dt FROM mytable
WHERE `Time` > TO_UNIXTIME(NOW() - INTERVAL 10 DAY)
) A GROUP BY dt;
Make sure you have an index on Time
ALTER TABLE mytable ADD INDEX TimeIndex (`Time`);
This will give you results with actual date values:
SELECT
COUNT(DISTINCT ip),
FROM_UNIXTIME(Time, '%m/%d/%Y') AS Day
FROM
tbl
WHERE
Time >= UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -10 DAY))
GROUP BY
FROM_UNIXTIME(Time, '%m/%d/%Y')
try this:
SELECT CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR) as dateoftime, COUNT(Ip) as cnt
FROM tablename
WHERE DATE(FROM_UNIXTIME(`Time`)) > DATE_SUB(current_timestamp, INTERVAL 10 DAY)
GROUP BY CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR)

SELECT records MySQL: between date + 1

Say I want to SELECT all records between two dates plus one record before and one record after that date? All records are ordered by date.
You could use a union combined with the limit statement. Something like what's below (untested, don't have access to mysql).
(select column from table where datefield > startdate and datefield < stopdate)
union
(select column from table where datefield < startdate order by datefield desc limit 1)
union
(select column from table where datefield > stopdate order by datefield limit 1)
This will give you the next row regardless of where it falls date-wise.
Thanks for syntax fix, ponies.
(select * from t where date < start_date order by date desc limit 1)
union (select * FROM t WHERE date between start_date and end_date)
union (select * from t where date > end_date order by date asc limit 1)
You can use functions to add or subtract values, like this:
select * from table where field1 < ADDDATE( CURTIME() , INTERVAL 1 DAY)
Check this link where there are some examples.
SELECT *
FROM table
WHERE date BETWEEN DATE_ADD(current_date(), INTERAL -1 DAY)
AND DATE_ADD(current_date(), INTERVAL 1 DAY);