I'm working on a job at the minute where all the products within the store need to be brought in and show how many orders have been put through in-between that time period which was easy to do, but it also in the same table needs to split the quantity of the orders of that product into the separate months that it was ordered in, is there any way to expand the data from one cell that's been group and do a count on it and then separate it into sub months?
$this->obDb->query ="SELECT vSku,fOrdertime,iOrderStatus,fPrice,SUM(iQty) as iQty,tShortDescription,fBuyprice as totalBuyPrice, vTitle FROM ".ORDERS.",".ORDERPRODUCTS." WHERE iOrderid_FK=iOrderid_PK AND ";
$this->obDb->query.=$statusquery;
if(isset($this->request['start_date']) & $this->request['start_date']>0){
$this->obDb->query.=" AND tmOrderDate >='".$this->request['start_date']."'";
}else{
$this->err=1;
$this->errMsg=INVALID_START_DATE."<br>";
}
if(isset($this->request['end_date']) & $this->request['end_date']>0){
$this->obDb->query.=" AND tmOrderDate <='".$this->request['end_date']."' GROUP BY vTitle";
}else{
$this->err=1;
$this->errMsg.=INVALID_END_DATE;
}
if($this->err==0){
$queryRs = $this->obDb->fetchQuery();
$recordCount=$this->obDb->record_count;
if($recordCount>0){
$this->ObTpl->set_var("TPL_VAR_FROMDATE", $this->libFunc->dateFormat2($this->request['start_date']));
$this->ObTpl->set_var("TPL_VAR_TODATE", $this->libFunc->dateFormat2($this->request['end_date']));
for($i=0;$i<$recordCount;$i++)
{
$this->ObTpl->set_var("TPL_VAR_STATUS","Incomplete");
if($queryRs[$i]->iOrderStatus==1){
$this->ObTpl->set_var("TPL_VAR_STATUS","Complete");
}
If I understand what you're asking you could try
SELECT datecol, COUNT(id)
FROM your_table
WHERE datecol BETWEEN date1 AND date2
GROUP BY productId, YEAR(datecol), MONTH(datecol)
ORDER BY datecol
Related
I'm trying to create a quick-fix script in order to delete some records and get the data back on track.
Originally I had sales records inserting and using a quantity value to create an equal number of records. So I if I inserted a record with a quantity value of 12, then I would insert 12 of that record. This gave each SKU it's own record so that individual ones could have dates updated.
However, this has changed and I now need to do it based on store locations rather than quantity so I have too many records in some cases.
If I run the script with the current query (for dealer number 145) it selects all skus they have ordered this year, as expected. I need to now run a delete statement that takes a row count of each sku and compares it to the storefront value from the join.
So, if storefronts = 10 and there are 25 records for that sku/dealer combo, then I need to delete the oldest 15. The logic here is for each sku/dealer combo where curdate() < expire_date there should only be x number of rows equal to storefronts
I'm trying to test this with dealer 145, who has 10 stores. So for all records this year where curdate() is before the expiration, there should be no more than 10 records for each sku, if that makes sense.
$selectRecords = "
SELECT p.sku_id, p.dealer_id, p.start_date, p.expire_date, p.quantity, s.storefronts, s.dealer_id
FROM placements p
inner join storefronts s on p.dealer_id = s.dealer_id
WHERE p.dealer_id = 145
and start_date > '2018-01-01'
order by start_date asc;
";
try{
$currentRecords = $MysqlConn->prepare($selectRecords);
$currentResult = $currentRecords->execute();
$currentCount = $currentRecords->rowCount();
echo "Open Orders: " . $currentCount . "\n"; //returns correct count
}catch(PDOException $ex){
echo "QUERY FAILED!: " .$ex->getMessage();
}
$currentArray = [];
while($row = $selectRecords->fetch(PDO::FETCH_ASSOC)){
//pseudo code
foreach(sku_id){
if(rowCount > storefronts){
delete starting with oldest start_date
until row count == storefronts
}
}
}
I feel like it shouldn't be too complicated but I'm really stuck on how to execute this exactly.
Here's a fiddle with data examples:
http://sqlfiddle.com/#!9/c0dd6
I have a problem i hope you can help me out with.
To break it down, i have a table in the database where i create events, it's called "dansetimer" and for that i have a table called for the participants on the events, called "transak"
I want to count how many events within a given time, had more than 20 participants.
I have made this for a start, and it's also very good, but i cant see how to count, how many events i end up with, of course i can just count the list manually, but i really want to get PHP to count it.
$hentgg = mysql_query("SELECT * FROM dansetimer WHERE dato BETWEEN $fra AND $til");
if(mysql_num_rows($hentgg)) {
while($visgg = mysql_fetch_array($hentgg)) {
$result=mysql_query("SELECT count(*) as total FROM transak WHERE produkt = '$visgg[id]'");
$data=mysql_fetch_assoc($result);
if($data['total'] > 20) {
echo $visgg[title];
}
}
} else {
echo "Ingen resultater";
}
With the above code i'm able to retrieve the events and get them listed.
With this code:
$result=mysql_query("SELECT count(*) as total FROM transak WHERE produkt = '$visgg[id]'");
$data=mysql_fetch_assoc($result);
I can count how many participants there are on the event, and with the if statement, testing if there are more than 20, i can hide the events, that dont have more participants.
But do you have a great idea for how i can write "Within the given time, you held 23 events with more than 20 participants" or something like that.
You could keep an extra counter in the loop, so you can see how many events have over 20 participants:
// At the start of your script
$large_events = 0;
...
// In your loop:
if($data['total'] > 20) {
echo $visgg[title];
$large_events++;
}
But I think it's easier, and probably faster too, to let SQL give you already some more details. In your solution it will query the participants for each event, so if someone has 1000 events, each with 20 participants or less, your database has to do 1001 queries, end the end result is 'Ingen resultater'.
So, change the query to this:
SELECT *
FROM
( SELECT
dt.*,
(SELECT count(*) FROM transak WHERE produkt = dt.id) AS total_participants
FROM dansetimer dt
WHERE dato BETWEEN $fra AND $til
)
WHERE
total_participants > 20
ORDER BY
dato,
title
This query returns only events with more than 20 participant, and it will return the number of participants per event. So you can just fetch this query result into a simple array and display each item to show the title, number of participants and other information. And the length of the array is the number of 'large' events.
PS: Did you know that the mysql_* functions are old and are removed in PHP 7? I think it's time for an upgrade to PDO.
Need to use this below query and you will get desired output (I want to count how many events within a given time, had more than 20 participants.).
SELECT count(*) FROM dansetimer dt WHERE (SELECT count(*) FROM transak WHERE produkt = dt.id)>=20 and dato BETWEEN $fra AND $til
Consider the following table
I need to return a list in descending order with the count of the member_nr's who is appearing the most frequent in the table where tournament = 'EPL' AND ROUND = '12'
EXAMPLE
The script should return the following results:
I thought about the problem and my logic for the problem reads like this
STEP1: GET member_nr one by one
$sql = "SELECT DISTINCT *
FROM winners
WHERE tournament='$tour' AND round='$round'";
LOOP(){ //get 1 member number
$mem_nr = ['mem_nr']; //assign mem_nr to variable
STEP2: GET the count(number of times) ^ABOVE^ member number appears in table
"$sql="SELECT *, count(member_nr) as nrWins
FROM winners
where member_nr ='$memNr' and tournament='$tournament' AND round='$round'";"
LOOP(){//get count
STEP 3: DISPLAY DATA
echo $row=['nrWins'] //Display Number Wins
echo $memNr
}//END LOOP
}//END LOOP
My Problem:
The above does not seem very efficient to me, im looking for the shortest most efficient way to return the count of member numbers in table above, any ideas / suggestions are welcomed
Try something like this:
SELECT *, COUNT(*) AS `wins`
FROM `winners`
WHERE `tournament` = '$tournament'
AND `round` = '$round'
GROUP BY `member_nr`
ORDER BY `wins` DESC
select tournament,round,member_nr,count(*)
from table
where tournament = 'EPL'
and round = 12
group by tournament,round,member_nr
order by count(*) desc
My query looks like this:
$result_portlist=mysql_query("
SELECT
portfolio AS the_port,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
GROUP BY portfolio
",$db);
$myrow_portlist=mysql_fetch_array($result_portlist);
if(mysql_num_rows($result_portlist)>0) {
do {
echo '<span> value1, vaule2, value3...</span>';
$result_portlist1=mysql_query("
SELECT
department AS the_department,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
GROUP BY department
",$db);
$myrow_portlist1=mysql_fetch_array($result_portlist1);
if (mysql_num_rows($result_portlist1)>0) {
do {
echo '<span> value1, vaule2, value3...</span>'
$result_portlist2=mysql_query("
SELECT
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE CONCAT(balance, insurance)!='0'
AND portfolio='$myrow_portlist[the_port]'
AND department='$myrow_portlist1[the_department]'
GROUP BY manager_name
",$db);
{
do {
echo '<span> value1, vaule2, value3...</span>';
} while ($myrow_portlist2=mysql_fetch_array($result_portlist2));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
} while ($myrow_portlist1=mysql_fetch_array($result_portlist1));
}
So this query takes hours to execute for table with 40,000+ rows with hundreds of combinations of portfolio+department+manager_name. What I thought was to make one query at start that would group values by manager_name and then let php group portfolio and department. After creating this query, my mind has just blown up and has no free memory left to think :)
Please advice me how to rearrange this query or how to simplify it to take less time to execute.
Thanks in advance.
EDIT: here is image, how my table (with nested tables) look like:
IMAGE
The reason why it takes a lot of time is because you are executing a massive amount of queries... Let's say you have 10 portfolios, in 10 departments, you'd make 100 queries. This amount is insane, and reducing the number of queries is pretty simple in your case.
I would simply grab all the data in one query, and use a 3 level group by with a rollup:
$result=mysql_query("
SELECT
portfolio AS the_port,
department AS the_department,
manager_name AS the_manager,
SUM(balance * course) AS the_balance,
SUM(insurance * course) AS the_insurance
FROM banks_all
WHERE
CONCAT(balance, insurance)!='0'
GROUP BY
portfolio,
department,
manager_name
with ROLLUP
ORDER BY the_port,the_department,the_manager;
",$db);
echo '<table>';
while($row = mysql_fetch_assoc($result)){
if($row['the_port'] === null){
//This is the big total row... Let's skip it for now shall we?
continue;
}
echo '<tr>';
if($row['the_department'] === null){
echo '<td>Portfolio: '.$row['the_port'].'</td>';
}else{
if($row['the_manager'] === null){
echo '<td>Department: '.$row['the_port'].'</td>';
}else{
echo '<td>Manager: '.$row['the_port'].'</td>';
}
}
echo '<td>'.$row['the_balance'].'</td>';
echo '<td>'.$row['the_insurance'].'</td>';
echo '</tr>';
}
echo '</table>';
This query will return all lines grouped by portfolio then grouped by department, then grouped by manager. This would return all rows from the finest point (your third while) but with ROLLUP you will also get a row for the other group by levels. This is exactly as if you would have done GROUP BY portfolio,department and GROUP BY portfolio inside the same query.
In the rolled up rows, the value of the keys omitted from the group by will be NULL. So you can easily check on the_manager, when it's null it means you have the full department, when the_department is null you have the full portfolio.
Hi i have such table information:
what i want to do with php with while or just in mysql, is to SUM (time_used) of the rows with status 44 until its reached row with status 55. after that it should begin from start with new summing.
first query should return 37, second 76 (keep in mind it should be universal, for unlimited occurrences of 55 status row)
i thought of a way with time/date filtering and have this:
select sum(time_used) as sumed
from timelog
where start_time > (select end_time from timelog where (status='55')
ORDER BY id DESC LIMIT 1) ORDER BY id DESC
but this works only for last combination of 44 and 55
i know i will need two way filtering( < end_time and > end_time) so it will work for all cases, but cant think of a way to do it in php
can anyone help me?
EDIT:
sqlfiddle whoever want it:
http://sqlfiddle.com/#!2/33820/2/0
There are two ways to do it: Plain SQL or PHP. If you treat thousands of rows, it may be interresting to choose between the two by testing performance.
Plain SQL
select project_id, task_id, user_id, sum(time_used) as time_used,
min(start_time) as start_time, max(end_time) as end_time, max(comment) as comment from
(select t.id, t.project_id, t.task_id, t.user_id, t.time_used,
count(t2.id) as count55, t.start_time, t.end_time, t.comment
from timelog t
left join timelog t2 on t.id>t2.id and t2.status=55 and t.task_id=t2.task_id
group by t.id) as t
group by count55;
I assume here that a task can belong to one user only
SQL and PHP
$link = mysqli_connect( ... );
$query = "select id, project_id, task_id, user_id, time_used, start_time, end_time, status
from timelog order by id";
$result = mysqli_query($link, $query);
$table = array();
$time_used = 0;
$start_sum = true;
$i = 0;
while($row = mysqli_fetch_assoc ($result)){
if($start_sum){
$table[$i] = $row;
$start_sum = false;
} else {
$table[$i]['time_used'] += $row['time_used'];
$table[$i]['end_time'] += $row['end_time'];
}
if($row['state'] == 55){
$i++;
$start_sum = true;
}
}
If two tasks can run in simultaneously, solution 1 will work, but solution 2 will need to be adapted in order to take this in account.
here is my intepretation:
http://sqlfiddle.com/#!2/33820/45
set #n=0;
select project_id, task_id, user_id,sum(time_used) from (
SELECT time_used,project_id, task_id, user_id,
#n:=if(status=55,#n+1,#n),
if(status=55,-1,#n) as grouper FROM timelog
) as t
where grouper>-1
group by grouper;
I'm neither a php nor MySQL programmer, but I can explain the logic you want to follow. You can then code it.
First, query your db and return the results to php.
Next, set two sum variables to 0.
Start looping through your query results. Increment the first sum variable until you reach the first row that has status 55. Once you do, start incrementing the second variable.
The tricky part will be to sort your query by the row number of the table. Here is a link that will help you with that part.