I have a mysql table - table1. It has ID (autoinc), dt (datetime), name (varchar) columns. When a visitor visits they can enter their name in the database. On some days their are no visitors.
From this, i'm trying to find if their is some way to make a list in php of all days for which their was at least 1 visitor.
Any ideas?
Select distinct date(dt) from table1
So then, in php you would do something like:
$result = mysql_query("select distinct date(dt) from table1");
while($row = mysql_fetch_array($result)){
echo $row[0] . "\n";
}
This would print each date on a different line.
Should give you a list of the unique dates that data was written to the table.
Updated to use date() instead of day()
*Updated to fix the missing parenthesis *
To extract only those dates.
SELECT DATE_FORMAT(dt, '%Y-%m-%d') AS the_date,
COUNT(*) AS visitors
FROM table
GROUP BY the_date
HAVING visitors > 0;
Related
I have a database name "d" and there is table name "t"...
t has two columns id and month...
I have to calculate no of ids in each month.
actually, I am taking an input in $monthyear, now I want to store count(id) of previous 25 month in a $row
I use this type of commands
$search = "SELECT * FROM `d`.`t` where id>2";
$result = mysqli_query($con, $search);
$row = mysqli_fetch_array($result);
please tell me a query which can do this trick and can you store it like
$row[0]="no of ids in the inputed month"
$row[1]="no of ids in the [inputed month - 1 month]"
$row[2]="no of ids in the [inputed month - 2 month]"
and so on....
note: both month and "years" do matter.
If not all month has IDs , then you need to use a derived table. Something like this:
SELECT t.monthyear, COALESCE(COUNT(s.monthyear),0) as numOfID
FROM(SELECT '012016' as monthyear
UNION ALL
SELECT '022016'
....) t
LEFT JOIN YourTable s
ON(t.monthyear = s.monthyear)
GROUP BY t.monthyear
My code goes like this,
$sql = "SELECT Month(time) as Month, Year(time) as Year,
title, COUNT(*) AS total FROM posts GROUP BY Year, Month ORDER BY time DESC";
$stmt = $conn->query($sql);
if ($stmt->num_rows > 0) {
while($row = $stmt->fetch_array()){
echo "<div class=title>" . $row["title"]. "</div>";
}
}
it is supposed to output 4 titles,
Bellavisa
Mist Neting
Turkey is cool!
Cock of the Rock
but it only outputs
Bellavisa
Turkey is cool!
Cock of the Rock
Note that bellavisa and mist neting are in the same year and month, (setting up an archive list)
EDIT
Here is some of the table data
title "bellavisa" content "yadadada" time "timestamp ..." Author "author"
title "mist nesting" content "yadadada" time "timestamp ..." Author "author"
Well, title is per post, so to get all the titles you should use no GROUP BY, while COUNT(*) is per month, so to get counts you need to GROUP BY the way you do, so in a simple SELECT you can either select one or another, but not both.
To select both, you need to use a subquery, something along the lines of
$sql = "SELECT Month(time) as Month, Year(time) as Year, title, (SELECT COUNT(*) FROM posts WHERE Month(time) = Month AND Year(time) = Year) AS total FROM posts ORDER BY time DESC;";
Effectively, the query selects all the posts, and for each post computes a count. It is not the most efficient way to do that, you can rewrite it using a join, if every post has a unique ID. But for a table with reasonable size this query will work just fine.
I have a table ipaddresses that contains IP ranges. Columns are: ipStart, ipEnd
Example of
ipStart: 3579374832
ipEnd: 3579374839
Now I want to select 300ish IP addresses from another table: visit_count. And based on those 300 addresses I want to check if the ip address is in the range of any of IPs in the table ipaddresses
My current code:
$results = $database->query("SELECT user_id,
DATE_FORMAT(last_visit, '%Y-%m-%d') as datumet,
cookieId, ipaddress
FROM `visit_count`
WHERE last_visit BETWEEN
'$firstDayOfMonth' AND '$lastDayOfMonth'
AND user_id = '$userId'
GROUP BY cookieId
ORDER BY last_visit ASC");
$rows = $database->loadObjectList($results);
foreach ( $rows as $row ) {
$ipaddressLong = ip2long($row->ipaddress);
// This is where its very very slow
$selO = $database->query("SELECT ipStart, ipEnd FROM `ipaddresses`
WHERE '$ipaddressLong' BETWEEN `ipStart` AND `ipEnd`");
$rowO = $database->getrow($selO);
}
The result is a really slow query that consumes a lot of cpu.
ipaddresses has indexes for both ipStart and ipEnd and contains around 50k rows.
How can I make this go faster?
A quick and dirty change to a single query using a JOIN:-
SELECT a.ipStart, a.ipEnd
FROM `ipaddresses` a
INNER JOIN
(
SELECT user_id, DATE_FORMAT(last_visit, '%Y-%m-%d') as datumet, cookieId, inet_aton(ipaddress ) AS ipaddressLong
FROM `visit_count`
WHERE last_visit BETWEEN '$firstDayOfMonth' AND '$lastDayOfMonth'
AND user_id = '$userId'
GROUP BY cookieId
) b
ON b.ipaddressLong BETWEEN a.ipStart AND a.ipEnd
Note that this could probably be simplified. However it depends on your use of GROUP BY cookieId . At the moment this is going to get one row per cookie id, but which row is undefined (ie, could be any user_id, ip address and last visit date that goes with that cookie id).
You can simplify the first select. You don't need to select any fields beyond ipaddress. You also don't need to order or group the result. If you want unique ipaddresses, just use distinct
select distinct ipaddress
from visit_count
where last_visit between '$firstDayOfMonth' and '$lastDayOfMonth'
and user_id = '$userId'
300 selects don't seem to be much, even with the second table having 50k rows. On my machine, even without indexes, it takes only a fraction of a second.
If you want to simplify it anyway, you can join the two tables with
select ipstart, ipend
from ipaddresses i
join visit_count v on inet_aton(v.ipaddress) between i.ipstart and i.ipend
where v.last_visit between '$firstDayOfMonth' and '$lastDayOfMonth'
and v.userid = '$userId'
1) Use better query like other suggested to you
2) Have you defined indexes for the field you need ?
3) Dont know if you use mysql or mysqli...anyway use fetch_assoc that is faster then fetch_array
with this 3 trick you should be ok
Here's my query:
$sql = $db->Query("SELECT a.uid, SUM(a.today_clicks) AS clicks, b.login FROM user_clicks a LEFT JOIN users b ON b.id = a.uid WHERE b.login != '' GROUP BY a.uid ORDER BY clicks DESC LIMIT 3");
Here's the code i'm using for getting the top 3 users for today:
<tr><?
$tops = $db->FetchArrayAll($sql);
foreach($tops as $top){
echo '<td>'.$top['login'].'</td>';
}
?></tr>
Which gives me the top 3 user names with the most clicks for today.
Here's my table structure:
Table name :"user_clicks"
6 fields
uid
module
total_clicks
today_clicks
max_clicks
daily_clicks
How can i get the same data but just from a day before?
Thanks in advance!
Here is one generic way to filter the columns with a date corresponding to yesterday:
SELECT
*
FROM
mytable a
WHERE
DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "Y-m-d") = DATE_FORMAT(a.date, "Y-m-d")
There is not enough information about your table structure to say how you would apply it in you case. So you will have to figure it out :)
I have two tables in my DB. One for one kind of items, second for another kind of items (some columns are same, some are different, first table contains 23 columns, second one contains 24 columns). Users can add these two kind of items. I somehow need to mere all these items and sort them by date (timestamp column), so most recently add items are shown first. Items are offers and demands (student accomodation).
Right now, I use two sql queries and offers are first (sorted by date) and then demands (sorted by date). But this system is bad, because with many items, users will have to go through many pages, before they find demand. So i need it to be combined.
Part of my code:
$sql = "SELECT * FROM table1 ORDER BY timestamp DESC";
if ($result = $mysqli->query($sql)) {
while($obj = $result->fetch_object()){
...
}}
$sql1 = "SELECT * FROM table2 ORDER BY timestamp DESC";
if ($result = $mysqli->query($sql1)) {
while($obj = $result->fetch_object()){
...
}}
you have to use union all in query
check out it
SELECT *
FROM (SELECT * FROM table1 WHERE "condition" UNION ALL SELECT * FROM table2 )
ORDER BY timestamp DESC;
select * from (
SELECT * FROM table1
UNION ALL
SELECT * FROM table2) raw
ORDER BY timestamp DESC
You should define the same column names and order to let them be unioned.