MySQL query return different results every time - mysql

I have the query
SELECT g.f_id as f_code
, ss.f_name as f_storage
, g.f_name as f_goods
, g.f_scancode
, s.f_price
, SUM(s.f_qty*s.f_type) as f_qty
, SUM(s.f_qty*s.f_type)*g.f_saleprice as f_totalsale
FROM a_store s
JOIN c_goods g
ON g.f_id = s.f_goods
JOIN c_storages ss
ON ss.f_id = s.f_store
JOIN a_header h
ON h.f_id = s.f_document
WHERE h.f_date <= '2020-06-22'
AND h.f_state = 1
GROUP
BY g.f_id
, ss.f_name
, g.f_name
, g.f_scancode
, s.f_price
HAVING SUM(s.f_qty*s.f_type) <> 0
ORDER
BY SUM(s.f_qty*s.f_type) asc
Every time this query returns different result and different rows count without the changes in the database. I cant understand, why.

I was change the version of mysql from 5.7 to 8.0 and problem was gone. Why it worked wrong on version 5.7 remains a mystery.

Related

Trying out this query in MS Access - Please let me who where i am wrong

The aim is to join the same table and retreive two different columns using where clause
SELECT a.analyst_assigned
, count(a.case_id) AS Pending
, count(b.case_id) AS Completed
, sum(b.total_errors) AS Errors
FROM cases_main as a
WHERE a.team_qc1_qa2 = "qa"
and a.q_status in ("Not Started","Under Review","Follow-up")
and a.p_date_worked between #03/08/2021# and #03/14/2021#
INNER JOIN cases_main as b
ON a.analyst_assigned = b.analyst_assigned
WHERE b.team_qc1_qa2 = "qa"
and b.q_status in ("Completed: No Error","Completed: Feedback")
and b.p_date_worked between #03/08/2021# and #03/14/2021#
GROUP
BY b.analyst_assigned;
Try this simpler approach:
SELECT a.analyst_assigned
, abs(sum(q_status Like "Completed*")) AS Pending
, abs(sum(q_status Not Like "Completed*")) AS Completed
, sum(b.total_errors) AS Errors
FROM cases_main as a
WHERE a.team_qc1_qa2 = "qa"
and a.p_date_worked between #03/08/2021# and #03/14/2021#
GROUP BY a.analyst_assigned

How optimize the performance of SerialNumbers by SalesInvoicesExploded?

I have the following query:
select sie.invoicedate sie_invoicedate
, sie.Silitem sle_item
, sie.Silitemcode sle_itemcode
, sie.Silitemdescription sle_itemdescription
, sie.Silnetprice sle_netprice
, sie.Silquantity sle_quantity
, sie.Silunitprice sle_unitprice
, ctr.ctr_code ctr_code
, ctr.ctr_name ctr_name
, ctr.parent_code parent_code
, ctr.parent_name parent_name
, gdlsn.ssrserialnumber serialnumber
from SalesInvoicesExploded sie
join customers#inmemorystorage ctr
on ctr.ctr_id = sie.invoiceto
join GoodsDeliveryLineSerialNumbers gdlsn
on gdlsn.salesorderlineid = sie.silid
where sie.invoicedate >= '2016-01-01'
and sie.invoicedate < '2016-01-03'
order
by sie.invoicedate
How can I get the serial numbers only from the date range? In the debugger I see a lot of requests to Exact Online.
For now, there isn't a very good filter possibility to get the result you want.
The problem is that there is no way to perform the gdlsn.salesorderlineid = sie.silid filter on the data set unless the data sets have been fetched from the other side.
Only specific filters are executed server-side (like your invoicedate >= '2016-01-01'). This is quite a hard nut to crack from the program side.
It would work if you can specify a filter that can be determined on beforehand, like that the date in GoodsDeliveryLineSerialNumbers.Created always comes after the invoicedate. It would mean a significant performance improvement if you can narrow down the set based on that date.
I suggest to use something like this, if possible:
select sie.invoicedate sie_invoicedate
, sie.Silitem sle_item
, sie.Silitemcode sle_itemcode
, sie.Silitemdescription sle_itemdescription
, sie.Silnetprice sle_netprice
, sie.Silquantity sle_quantity
, sie.Silunitprice sle_unitprice
, ctr.ctr_code ctr_code
, ctr.ctr_name ctr_name
, ctr.parent_code parent_code
, ctr.parent_name parent_name
, gdlsn.ssrserialnumber serialnumber
from SalesInvoicesExploded sie
join customers#inmemorystorage ctr
on ctr.ctr_id = sie.invoiceto
join GoodsDeliveryLineSerialNumbers gdlsn
on gdlsn.salesorderlineid = sie.silid
where sie.invoicedate >= '2016-01-01'
and sie.invoicedate < '2016-01-03'
-- add the following line, use a date that for sure will yield the rows:
and gdlsn.created >= '2015-12-01'
--
order
by sie.invoicedate

Convert time "28:45" to "4:45" MySQL

I'm looking for a way to order my results based on the actual time. In my table yo can see values like:
1,23:45
2,9:45
3,27:43
When I do a query I would like to know how to order them based on their actual 24 hour time.
Ex:
3,3:43
2,9:45
1,23:45
Notice how it changes 27:43 to 3:43, and creates the order.
Where I am using it, in this query:
SELECT *,COALESCE(ADDTIME(s.`departure_time`,SEC_TO_TIME(rt.delay)),s.`departure_time`) as `rt_time` FROM `stop_times` s INNER JOIN `trips` t ON s.`trip_id` = t.`trip_id` INNER JOIN `stops` st ON st.`stop_id` = s.`stop_id` INNER JOIN `routes` r ON r.`route_id` = t.`route_id` LEFT JOIN `rt_trips` rt ON t.`trip_id` = rt.`trip_id` where (s.`stop_id` = 'CB900') and ( ( s.`departure_time` >= '00:50' and s.`departure_time` <= '05:50') OR ( s.`departure_time` >= '24:50' and s.`departure_time` <= '29:50') ) and (s.`pickup_type` = '0') and (t.`service_id` IN ('removed to make it easier')) HAVING (`rt_time` BETWEEN '01:50' and '05:50' ) ) OR ( `rt_time` BETWEEN '25:50' and '29:50' ) ORDER BY `order` ASC
Explanation:
Information is a transit schedule, that may go forward onto the next day which may be a saturday. So, times may become 25:50, where that means 1:50 the next day.
Thanks
Cyrus
Hmmm, if you just want to get a value between 0 and 24 hours, then I would do:
select concat(mod(substring_index(time_column, ':', 1) + 0, 24), ':',
substring_index(time_column, ':', -1)
)
Try this function on the time_column
concat(mod(substr(time_column,1,INSTR(time_column, ':')-1),24)
,substr(time_column,INSTR(time_column, ':'),3)
)
You might need to cast date to string to integer, do the maths, and again cast it to time. But the fiddle version seems to work properly on varchar to integer conversion. Check this
http://sqlfiddle.com/#!9/ff60f9/1

mysql statement prestashop error "checkedFrom"

In prestashop, i want to create a new SQL statement for export rows that i want. Here is my code:
SELECT nx7k_orders.reference
, nx7k_orders.date_add
, nx7k_order_detail.product_name
, nx7k_order_detail.product_quantity
, nx7k_customer.firstname
, nx7k_customer.lastname
FROM nx7k_orders
JOIN nx7k_order_detail
ON nx7k_order_detail.id_order = nx7k_orders.id_order
JOIN nx7k_customer
ON nx7k_customer.id_shop = nx7k_order_detail.id_shop
But, when I click Save button, on top it said, error "checkedFrom"
i think only works if you give alias to the tables:
SELECT no.reference,
no.date_add,
nod.product_name,
nod.product_quantity,
nc.firstname,
nc.lastname
FROM nx7k_orders no
JOIN nx7k_order_detail nod
ON nod.id_order = no.id_order
JOIN nx7k_customer nc
ON nc.id_shop = nod.id_shop

Simplify sql query to obtain one line per id

I have a multi-table SQL query.
My need is: The query should I generate a single line by 'etablissement_id' ... and all information that I want to be back in the same query.
The problem is that this query is currently on a table where "establishment" may have "multiple photos" and suddenly, my query I currently generates several lines for the same id...
I want the following statement - LEFT JOINetablissementContenuMultimediaON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId - only a single multimedia content is displayed. Is it possible to do this in the query below?
Here is the generated query.
SELECT DISTINCT `etablissement`. * , `etablissementContenuMultimedia`. * , `misEnAvant`. * , `quartier`. *
FROM `etablissement`
LEFT JOIN `etablissementContenuMultimedia` ON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId
LEFT JOIN `misEnAvant` ON misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id
LEFT JOIN `quartier` ON quartier_id = etablissement_quartierId
WHERE (
misEnAvant_typeMisEnAvantId =1
AND (
misEnAvant_dateDebut <= CURRENT_DATE
AND CURRENT_DATE <= misEnAvant_dateFin
)
)
AND (
etablissement_isActive =1
)
ORDER BY `etablissement`.`etablissement_id` ASC
LIMIT 0 , 30
Here is the code used ZF
public function find (){
$db = Zend_Db_Table::getDefaultAdapter();
$oSelect = $db->select();
$oSelect->distinct()
->from('etablissement')
->joinLeft('etablissementContenuMultimedia', 'etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId')
->joinLeft('misEnAvant', 'misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id')
->joinLeft('quartier', 'quartier_id = etablissement_quartierId ')
->where ('misEnAvant_typeMisEnAvantId = 1 AND (misEnAvant_dateDebut <= CURRENT_DATE AND CURRENT_DATE <= misEnAvant_dateFin) ')
->where ('etablissement_isActive = 1')
->order(new Zend_Db_Expr('RAND()'));
$zSql = $oSelect->__toString();
if(isset($_GET['debug']) AND $_GET['debug'] == 1)
echo $zSql ;
//die();
$oResultEtablissement = $db->fetchAll($oSelect);
return $oResultEtablissement ;
}
Can you help me?
Sincerely,
If you are looking to have only one of the media displayed out of many regardless of which it may be then you can just add a limit to the query? After that you can tweak the query for ASCending or DESCending perhaps?
Is this query supposed to have images (or image as it were) for one establishment, or one image each for each active establishment? I see you have a limit 0,30 which means you're likely paginating....
If the result you want is a search for only one establishment, and the first image it comes to would work fine .. just use "limit 1" and you'll only get one result.
I took the time to redo the whole model of the database ... and now it works. There was no solution for a system as flawed