Select count from a table with a Where on another table - php

I have two tables
oc2_visits (fields: id_ad)
oc2_ads (fields: published)
I need to count the visits by grouping the id_ad, and that works, but I need also that the first 9 results have been published not more that 25 days ago.
This is the query I have at the moment:
SELECT count(v.id_ad) AS visits,
v.id_ad,
a.published
FROM oc2_visits AS v,
oc2_ads AS a
WHERE DATE(a.published) >= DATE_SUB(NOW(), INTERVAL 25 DAY)
GROUP BY v.id_ad
ORDER BY visits DESC LIMIT 0,9
but when I try to enter the query in phpmyadmin, it crashes.
What am I doing wrong?

I think you forgot to parse DATE_SUB(NOW(), INTERVAL 25 DAY) into DATE while comparing with a DATE. Hope it'll work.
SELECT count(v.id_ad) AS visits,
v.id_ad,
a.published
FROM oc2_visits AS v,
oc2_ads AS a
WHERE DATE(a.published) >= DATE(DATE_SUB(NOW(), INTERVAL 25 DAY))
GROUP BY v.id_ad
ORDER BY visits DESC LIMIT 0,9

Presumably the root of your problem is the cartesian product between two tables. Simple rule: Never use comma in the from clause. Always use explicit join syntax.
I imagine the query you want looks something like this:
SELECT count(v.id_ad) AS visits, v.id_ad, a.published
FROM oc2_visits v join
oc2_ads a
ON v.id_ad = a.id_ad
WHERE DATE(a.published) >= DATE_SUB(NOW(), INTERVAL 25 DAY)
GROUP BY v.id_ad
ORDER BY visits DESC
LIMIT 0, 9;

Related

Min value from Database in MySQL

Am trying to find the min value from past 30 days, in my table there is one entry for every day, am using this query
SELECT MIN(low), date, low
FROM historical_data
WHERE name = 'bitcoin'
ORDER BY STR_TO_DATE(date,'%d-%m-%Y') DESC
LIMIT 7
But this value not returing the correct value. The structure of my table is
Table structure
And table data which is store is like this
Table data style
Now what i need is to get the minimum low value. But my query not working it give me wrong value which even did not exist in table as well.
Updates:
Here is my updated Table Structure.
enter image description here
And here is my data in this table which look like this
enter image description here
Now if you look at the data, i want to check the name of token omisego and fatch the low value from past 7 days which will be from 2017-12-25 to 2017-12-19
and in this cast the low value is 9.67, but my current query and the query suggested by my some member did not brings the right answer.
Update 2:
http://rextester.com/TDBSV28042
Here it is, basically i have more then 1400 coins and token historical data, which means that there will me more then 1400 entries for same date like 2017-12-25 but having different name, total i have more then 650000 records. so every date have many entries with different names.
To get the lowest row per group you could use following
SELECT a.*
FROM historical_data a
LEFT JOIN historical_data b ON a.name = b.name
AND a.low > b.low
WHERE b.name IS NULL
AND DATE(a.date) >= '2017-12-19' AND DATE(a.date) <= '2017-12-25'
AND a.name = 'omisego'
or
SELECT a.*
FROM historical_data a
JOIN (
SELECT name,MIN(low) low
FROM historical_data
GROUP BY name
) b USING(name,low)
WHERE DATE(a.date) >= '2017-12-19' AND DATE(a.date) <= '2017-12-25'
AND a.name = 'omisego'
DEMO
For last 30 day of 7 days or n days you could write above query as
SELECT a.*, DATE(a.`date`)
FROM historical_data2 a
LEFT JOIN historical_data2 b ON a.name = b.name
AND DATE(b.`date`) >= CURRENT_DATE() - INTERVAL 30 DAY
AND DATE(b.`date`) <= CURRENT_DATE()
AND a.low > b.low
WHERE b.name IS NULL
AND a.name = 'omisego'
AND DATE(a.`date`) >= CURRENT_DATE() - INTERVAL 30 DAY
AND DATE(a.`date`) <= CURRENT_DATE()
;
DEMO
But note it may return more than one records where low value is same, to choose 1 row among these you have specify another criteria to on different attribute
Consider grouping the same and running the clauses
SELECT name, date, MIN(low)
FROM historical_data
GROUP BY name
HAVING name = 'bitcoin'
AND STR_TO_DATE(date, '%M %d,%Y') > DATE_SUB(NOW(), INTERVAL 30 DAY);
Given the structure, the above query should get you your results.
// Try this code ..
SELECT MIN(`date`) AS date1,low
FROM historical_data
WHERE `date` BETWEEN now() - interval 1 month
AND now() ORDER by low ASC;

how can i write as one query to get count in mysql

I want to get the today count of users and yesterday's users count for that i want to write only one query how can i do that..?
these are my queries I want only one query:
SELECT COUNT(*) FROM visitors group by visited_date ORDER by visited_date DESC limit 1,1 as todayCount
SELECT COUNT(*) FROM visitors group by visited_date ORDER by visited_date DESC limit 1,0 as yesterdayCount
My expected results or only 2 columns
todayCount yesterdayCount
2 4
This should do the trick:
SELECT COUNT(CASE
WHEN visited_date = CURDATE() THEN 1
END) AS todayCount ,
COUNT(CASE
WHEN visited_date = CURDATE() - INTERVAL 1 DAY THEN 1
END) AS yesterdayCount
FROM visitors
WHERE visited_date IN (CURDATE(), CURDATE() - INTERVAL 1 DAY)
GROUP BY visited_date
ORDER by visited_date
If you know the current and previous date, then you can do:
SELECT SUM(visited_date = CURDATE()) as today,
SUM(visited_date = CURDATE() - interval 1 day) as yesterday
FROM visitors
WHERE visited_date >= CURDATE() - interval 1 day;
If you don't know the two days, then you can do something similar, getting the latest date in the data:
SELECT SUM(v.visited_date = m.max_vd) as today,
SUM(v.visited_date < m.max_vd) as yesterday
FROM visitors v CROSS JOIN
(SELECT MAX(v2.visited_date) as max_vd FROM visitors v2) as m
WHERE v.visited_date >= m.max_vd - interval 1 day
Just try this simple query
select visited_date as date, COUNT(*) as count from `visitors`
group by `visited_date` order by `visited_date` asc
It will produce output as
It will work for you.
Try this:
$sqlToday = "Select COUNT(*) FROM menjava WHERE DATE(date_submitted)=CURRENT_DATE()";
$sqlYesterday = "Select COUNT(*) FROM menjava WHERE DATE(dc_created) = CURDATE() - INTERVAL 1 DAY";

Joining two select queries on a results field

I'm trying to join a query results on a field, 'min' - which is the hour:min of the event. I have two different select queries in one and I'm trying UNION (which may not be right, just trying different things, I find MySQL documentation very difficult to read).
So I want
H:M and then the result of addCount and projectsNum - so for each hour/min I have the stats.
Where am I going wrong?
(
SELECT
DATE_FORMAT(`when`, '%H:%i') as `min`,
COUNT(`ipAddress`) AS `addCount`
FROM `metric` m
WHERE `when` BETWEEN DATE_SUB(NOW(), INTERVAL 3 HOUR) AND NOW()
GROUP BY DAY(`when`), HOUR(`when`), MINUTE(`when`)
)
UNION
(
SELECT
DATE_FORMAT(v.`created`, '%H:%i') as `min`,
COUNT(v.`projID`) as `projectsNum`
FROM `projects` v
WHERE v.`created` BETWEEN DATE_SUB(NOW(), INTERVAL 3 HOUR) AND NOW()
GROUP BY DAY(v.`created`), HOUR(v.`created`), MINUTE(v.`created`)
)
UNION just appends a set of results to another set of results.
You need to use your second query as a sub-query:
SELECT
DATE_FORMAT(`when`, '%H:%i') as `min`,
COUNT(`ipAddress`) AS `addCount`,
projects_subquery.`projectsNum`
FROM `metric` m
JOIN (
SELECT
DATE_FORMAT(v.`created`, '%H:%i') as `min`,
COUNT(v.`projID`) as `projectsNum`
FROM `projects` v
WHERE v.`created` BETWEEN DATE_SUB(NOW(), INTERVAL 3 HOUR) AND NOW()
GROUP BY DAY(v.`created`), HOUR(v.`created`), MINUTE(v.`created`)
) AS projects_subquery ON projects_subquery.`min` = m.`min`
WHERE `when` BETWEEN DATE_SUB(NOW(), INTERVAL 3 HOUR) AND NOW()
GROUP BY DAY(`when`), HOUR(`when`), MINUTE(`when`)
This query probably performs terribly. I just brute-force copy-pasted from your original query to make it syntactically correct, but there must be a way to optimize it.

MySQL Query Problem with INTERVAL, need 0 if no data provided

i have the following statement:
SELECT
count(rs.rsc_id) as counter
FROM shots as rs
where rsc_rs_id = 345354
AND YEAR(rs.timestamp) = YEAR(DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
GROUP BY DATE_FORMAT(rs.timestamp,'%Y%m')
rs.timestamp is a unix timestamp
Output would be like for each row / month a numeric like '28'
It Works fine, but if i have inconsistent data, like only for the past three month (not for all six month), i get no return from my Database. I would like to have every time there is not data for this month, 0 returned...
any suggestion?
i thought about some case statements, but this seems not so good...
thanks!!
For only 6 months, a date table seems unnecessary, although this looks complicated (it really isn't!)
SELECT DATE_FORMAT(N.PivotDate,'%Y%m'), count(rs.rsc_id) as counter
FROM (
select ADDDATE(CURDATE(), INTERVAL N MONTH) PivotDate
FROM (
select 0 N union all
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6) N) N
LEFT JOIN shots as rs
ON rsc_rs_id = 345354
AND DATE_FORMAT(N.PivotDate,'%Y%m')=DATE_FORMAT(FROM_UNIXTIME(rs.timestamp),'%Y%m')
GROUP BY DATE_FORMAT(N.PivotDate,'%Y%m')
In such cases it's common to use a table of dates with all dates (e.g. from 1/1/1970 to 31/12/2999) and LEFT JOIN your data to that table.
See an example in the answer here: mysql joins tables creating missing dates
If you create a dates table you can use:
SELECT
DATE_FORMAT(d.date,'%Y%m') AS `month`, count(rs.rsc_id) AS `counter`
FROM dates d
LEFT JOIN shots as rs
ON d.date = FROM_UNIXTIME(rs.timestamp)
AND rs.rsc_rs_id = 345354
WHERE d.date > DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
AND d.date < CURDATE()
GROUP BY DATE_FORMAT(d.date,'%Y%m');

PHP / MySQL - Construct a SQL query

Im having a little trouble constructing a query.
I have a table with 3 columns.
id - day - pageviews
What i basically want to do is get 8 id's from the table where the pageviews are the highest from the last 60 days.
The day column is a datetime mysql type.
Any help would be great, im having a little trouble figuring this one out.
Cheers,
Almost the same as TuteC posted, but you'll need a group by to get what you need...
SELECT id, SUM(pageviews) totalViews
FROM table
WHERE DATE_SUB(CURDATE(), INTERVAL 60 DAY) <= day
GROUP BY id
ORDER BY totalViews DESC
LIMIT 8
Do something like this:
SELECT id FROM table_name
WHERE DATE_SUB(CURDATE(),INTERVAL 60 DAY) <= day
ORDER BY pageviews DESC
LIMIT 8;
$sixtyDaysAgo = date('Y-m-d',strtotime('-60 days'));
$sql = "SELECT id
FROM table_name
WHERE day >= '$sixtyDaysAgo 00:00:00'
ORDER BY pageviews DESC
LIMIT 8";
If each row is a number of pageviews for that day, and you're looking for the highest total sum of 60 days' worth, then you'll need to total them all and then grab the top 8 from among those totals, like so:
$sql = "SELECT id
FROM (
SELECT id, SUM(pageviews) AS total_pageviews
FROM table_name
WHERE day >= '$sixtyDaysAgo 00:00:00'
GROUP BY id
) AS subselect
ORDER BY total_pageviews DESC
LIMIT 8";

Categories