I am facing problem while running the below query. It takes longer time for short month duration and time out for longer duration.
SELECT DISTINCT rcs.ID,
rcs.UniqueID,
rcs.ReferanceNo,
rcs.OrderDateActual,
rcs.DelivaredToCus,
rcs.PacketNumber,
rcs.PackingCharge,
rcs.TransportCharge,
rcs.OtherAdjustment,
SUM(rcsd.TotalPrice) AS TotalPrice
FROM regular_challan_sales rcs
LEFT JOIN regular_challan_sales_details rcsd ON rcsd.UniqueID = rcs.UniqueID
WHERE rcs.OrderDateActual >= '2013-12-01'
AND rcs.OrderDateActual <= '2014-05-01'
GROUP BY rcs.UniqueID
ORDER BY rcs.OrderDateActual ASC
I need a quick solution please.
Related
I'm using doctrine as an ORM layer but by putting a plain mysql query in my database tool i got the same results. So my problem:
I have an invoices table, invoice_items and invoice_payments table and what i would like to get as an result is all invoices that are not paid or at least not fully paid yet. I know that the query should be almost correctly because its giving the correct amount of items back... the only thing is that it is multiplying the amount by a number of probably joined rows.
So the query that i have for now:
select invoice.*, sum(item.amount * item.quantity) as totalDue,
sum(payment.amount) as totalPaid
from invoices as invoice
left join invoice_items as item on item.invoice_id = invoice.id
left join invoice_payments as payment on payment.invoice_id = invoice.id
and payment.status = 'successful'
where invoice.invoice_number is not null
and invoice.sent_at is not null
and invoice.due_date >= '2018-05-15'
group by invoice.id
having count(payment.id) = 0
or sum(payment.amount) < sum(item.amount * item.quantity)
order by invoice.issue_date desc, sum(payment.amount) desc;
As you can see i also have totalDue and totalPaid in my select (those are for reference only and should be removed if the query is correct).
What i saw is that the amount is multiplied by six (because it has 6 items in the payments table).
So maybe someone could help me pointing in the right direction that it doesn't do the multiplying on the totalDue. I was thinking its probably because the group by but without my query is failing.
By simply using a distinct in my query i fixed the problem.
select invoice.*, sum(distinct(item.amount * item.quantity)) as totalDue,
sum(payment.amount) as totalPaid
from invoices as invoice
left join invoice_items as item on item.invoice_id = invoice.id
left join invoice_payments as payment on payment.invoice_id = invoice.id
and payment.status = 'successful'
where invoice.invoice_number is not null
and invoice.sent_at is not null
and invoice.due_date >= '2018-05-15'
group by invoice.id
having count(payment.id) = 0
or sum(payment.amount) < sum(distinct(item.amount * item.quantity))
order by invoice.issue_date desc, sum(payment.amount) desc;
I would like to thank all the people who had taken the time to re-style my question ;-)
I have table having list of football matches. it has columns like match_id, team a score, team 2 score, rounds, match_date etc.
I need all rows from database with highest margin of that round
margin is difference of team a score and team b score.
my query is
SELECT *,( SELECT MAX(ABS((z.home_score - z.away_score)))
FROM tblform_matches z
WHERE YEAR(z.match_date) = YEAR(tblform_matches.match_date)
AND z.round = tblform_matches.round ) as highest_margin
from tblform_matches where some condtion
it is a simplified query where some condition is a large query string to select some specified matches according to filter.
currently there are around 5000 matches in database.
Due to sub-query my page is taking 4 more seconds to load.
there are 9 matches in each round and there are more than 20 rounds in every year
I am executing the above query for every team in php loop. I cant change this thing. as there are a lot of calculation for showing stats.
Sorry if my question is uncleared, I am here if I missed something as I am a new bee to stakoverflow
Thanks in advance.
This is your query:
SELECT m.*,
(SELECT MAX(ABS((m2.home_score - m2.away_score)))
FROM tblform_matches m2
WHERE YEAR(m2.match_date) = YEAR(m.match_date) AND
m2.round = m.round
) as highest_margin
from tblform_matches m
where some condition;
Presumably, the best way to optimize this is to focus on . Oh well. You will want the right indexes there.
Indexes are clearly the solution, but you have a problem because the of the year function. And easy solution is to use indequalities:
SELECT m.*,
(SELECT MAX(ABS((m2.home_score - m2.away_score)))
FROM tblform_matches m2
WHERE m2.round = m.round
(m2.match_date >= makedate(year(m.match_date), 1) and
m2.match_date < makedate(year(m.match_date) + 1, 1)
)
) as highest_margin
from tblform_matches m
where some condtion;
The best index for the subquery is tblform_matches(round, match_date, home_score, away_score). The first two columns are used for the where clause. The second two for the select.
Note: if you made two relatively minor changes to the data structure, this could work even better. Add a column for the year of the match date (redundant, but important for indexing). And, add a column for the absolute value of the difference between the scores. Then the query would be:
SELECT m.*,
(SELECT MAX(score_diff)
FROM tblform_matches m2
WHERE m2.round = m.round and m2.matchyear = m.matchyear
) as highest_margin
from tblform_matches m
where some condtion;
The index on this query would be: tblform_matches(round, matchyear, score_diff) and the lookup should be pretty fast.
EDIT:
You may get better performance with an explicit join:
SELECT m.*, m2.highest_margin
from tblform_matches m join
(select MAX(ABS((m2.home_score - m2.away_score))) as highest_margin
from tblform_matches m2
group by year(m2.match_date), m2.round
) m2
on year(m.match_date) = year(m2.match_date) and m2.round = m.round
where some condition;
I am trying to calculate the difference of values list coming from a database.
I would like to achieve it using php or mysql, but I do not know how to proceed.
I have a table named player_scores. One of its rows contains the goals scored.
Ex.
pl_date pl_scores
03/11/2014 18
02/11/2014 15
01/11/2014 10
I would like to echo the difference between the goals scored during the matches played in different dates.
Ex:
pl_date pl_scores diff
03/11/2014 18 +3
02/11/2014 15 +5
01/11/2014 10 no diff
How can I obtain the desired result?
You seem to want to compare a score against the score on a previous row.
Possibly simplest if done using a a sub query that gets the max pl_date that is less than the pl_date for the current row, then joining the results of that sub query back against the player_scores table to get the details for each date:-
SELECT ps1.pl_date, ps1.pl_scores, IF(ps2.pl_date IS NULL OR ps1.pl_scores = ps1.pl_scores, 'no diff', ps1.pl_scores - ps1.pl_scores) AS diff
FROM
(
SELECT ps1.pl_date, MAX(ps2.pl_date) prev_date
FROM player_scores ps1
LEFT OUTER JOIN player_scores ps2
ON ps1.pl_date > ps2.pl_date
GROUP BY ps1.pl_date
) sub0
INNER JOIN player_scores ps1
ON sub0.pl_date = ps1.pl_date
LEFT OUTER JOIN player_scores ps2
ON sub0.prev_date = ps2.pl_date
There are potentially other ways to do this (for example, using variables to work through the results of an ordered sub query, comparing each row with the value stored in the variable for the previous row)
SELECT score FROM TABLE WHERE DATE = TheDateYouWant
$score = $data['score'];
SELECT score FROM TABLE WHERE date = dateYouWant
$difference = $score - $data['score'];
Something like this?
You could use two queries, one to get the value to use in the comparison (in the example below is the smaller number of scores) and the second one to get the records with a dedicated column with the difference:
SELECT MIN(pl_scores);
SELECT pl_date, pl_scores, (pl_scores - minScore) as diff FROM player_scores;
Or, using a transaction (one query execution php side):
START TRANSACTION;
SELECT MIN(Importo) FROM Transazione INTO #min;
SELECT Importo, (Importo - #min) as diff FROM Transazione;
select *,
coalesce(
(SELECT concat(IF(t1.pl_scores>t2.pl_scores,'+',''),(t1.pl_scores-t2.pl_scores))
FROM tableX t2 WHERE t2.pl_date<t1.pl_date ORDER BY t2.pl_date DESC LIMIT 1)
, 'no data' ) as diff
FROM tableX t1
WHERE 1
order by t1.pl_date DESC
The Table I have has temperatures, locations and datetime and other data that isn't currently used. Message is the temperature and locationmap is where the sensor is ie, lounge, kitchen, outside!)
Query :
SELECT
t1.*
FROM
temperatures t1
JOIN (
SELECT
locationmap
, MAX(timeof) AS timeof
FROM
temperatures
GROUP BY
locationmap
) AS t2
ON t1.locationmap = t2.locationmap AND t1.timeof = t2.timeof
WHERE
DATE(t1.timeof) BETWEEN DATE_SUB(CURDATE(), INTERVAL 5 MINUTE) AND CURDATE()";
Resulting PHP code to display current temperatures;
// Print out result
while($row = mysql_fetch_array($result)){
echo $row['locationmap']. " - ". $row['message']. " #". $row['timeof'];
echo "<br />";
}
Just want it to display the latest temperature for each location, which it currently does, but I was wondering if this the best optimised query for speed, as at the moment it takes 7secs to display results!? Mind u I have a slow server, but I'm the only user.
Thx.
FYI.
Can't say without table create statements, more information about indexes and storage engine
And please make your SQL code more readable in your PHP code, It's damn hard to read like this.
SELECT
t1.*
FROM
temperatures t1
JOIN (
SELECT
locationmap
, MAX(timeof) AS timeof
FROM
temperatures
GROUP BY
locationmap
) AS t2
ON t1.locationmap = t2.locationmap AND t1.timeof = t2.timeof
WHERE
DATE(t1.timeof) BETWEEN DATE_SUB(CURDATE(), INTERVAL 5 MINUTE) AND CURDATE()
The same query but more readable
And thanks for the minus 1, because i tryed to help...
This query should run sightly faster
SELECT
t1.locationmap
, t1.message
, t1.timeof
FROM
temperatures AS t1
JOIN (
SELECT
locationmap
, MAX(timeof) AS timeof
FROM
temperatures
GROUP BY
locationmap
) AS t2
ON t1.locationmap = t2.locationmap AND t1.timeof = t2.timeof
WHERE
DATE(t1.timeof) BETWEEN DATE_SUB(CURDATE(), INTERVAL 5 MINUTE) AND CURDATE()
And make sure you have a covering BTREE (if you use MyISAM or innodb indexes are already BTREE) index on locationmap, timeof and message (optional) (be sure you build the index like this)
Please note that inserts, updates and deleted run sightly slower because of the covering index.
So try to multiinsert to keep the speed up.
I`m trying to query my database with 4 queries, each query will give me the number of rows that I need but I faced with but I notice when I do the query on the server that strong, everything works fast (relatively), but if I make it a relatively simple server that I deserve the maximum working time (30 seconds, the limit execution time(PHP)).
my while loop works with list of MokedCcode each MokedCcode goes into the queries and go to the next MokedCcode.
Notes :
1) I know it will be proportional to the number of MokedCcode-s.
2) I need to increase the execution time limit?
1) there is more efficient way to make those queries? maybe I dont use the mysql features right.
for example the first query called $emerg, this query need to give me the number of rows between dates, where WCODE have priority 1 and it has to be match of MokedCcode on both tables ( t and e ).
$emerg = mysql_num_rows(mysql_query("SELECT t.*,e.DISCODE,e.AREA,e.COLOR,e.PRIORITY FROM $tbl_name AS t
LEFT JOIN eventcodes AS e ON t.MokedCcode = e.MokedCcode AND t.WCODE=e.WCODE
WHERE (t.MokedCcode='$MokedCcode' ) AND e.PRIORITY='1'
AND t.ndate BETWEEN '$start' AND '$end' ORDER By `id` DESC "));
In addition I added the 3 more queries, I would like to get some advice how to make it faster Or I dont have any choice and keep it like that.
The 3 other queries:
$regular = mysql_num_rows(mysql_query("SELECT t.*,e.DISCODE,e.AREA,e.COLOR,e.PRIORITY FROM $tbl_name AS t
LEFT JOIN eventcodes AS e ON t.MokedCcode = e.MokedCcode AND t.WCODE=e.WCODE
WHERE (t.MokedCcode='$MokedCcode' ) AND e.PRIORITY!='1'
AND t.ndate BETWEEN '$start' AND '$end' ORDER By `id` DESC "));
$regHandled = mysql_num_rows(mysql_query("SELECT t.*,e.DISCODE,e.AREA,e.COLOR,e.PRIORITY FROM $tbl_name AS t
LEFT JOIN eventcodes AS e ON t.MokedCcode = e.MokedCcode AND t.WCODE=e.WCODE
WHERE (t.MokedCcode='$MokedCcode' ) AND e.PRIORITY!='1'
AND t.EventHandling!='0' AND t.ndate BETWEEN '$start' AND '$end' ORDER By `id` DESC "));
$emergHandled = mysql_num_rows(mysql_query("SELECT t.*,e.DISCODE,e.AREA,e.COLOR,e.PRIORITY FROM $tbl_name AS t
LEFT JOIN eventcodes AS e ON t.MokedCcode = e.MokedCcode AND t.WCODE=e.WCODE
WHERE (t.MokedCcode='$MokedCcode' ) AND e.PRIORITY='1'
AND t.EventHandling!='0' AND t.ndate BETWEEN '$start' AND '$end' ORDER By `id` DESC "));
I didn't exactly understand what you are trying to achieve.
If you just want the count Why are you selecting all the rows? cant you use COUNT() MySQL function? It is always slow to get all the data to your script and then count the rows.
Even if you want to select all those columns, try using t.field1, t.field2, ... instead of t.*