Rows are being excluded from SQL query when using MAX - mysql

I have table A
A
MID----Totals
1 --------- 3
5 ----------3
2 ----------2
4 ----------1
When this is run
SELECT * FROM A HAVING A.totals=3;
Gives as expected
MID----Totals
1 --------- 3
5 ----------3
But When I run
SELECT * FROM A HAVING (A.totals=(max(A.totals));
only gives
MID----Totals
1 --------- 3
And not the second row. I need to be able to use the max value as the numbers in the total column will change. How can I do this?

use this query :
SELECT * FROM A HAVING A.totals=(SELECT max(B.totals) FROM A B) ;
Fiddle

HAVING is used with GROUP BY aggregates
Use WHERE instead
SELECT * FROM A WHERE A.totals = (SELECT MAX(A.totals) FROM A)

We can do something like this:
SELECT d.mid
, d.totals
FROM ( SELECT MAX(s.totals) AS max_totals FROM A s ) t
JOIN A d
ON d.totals = t.max_totals
ORDER
BY d.mid
, d.totals
We can return an equivalent result like this:
SELECT d.mid
, d.totals
FROM A d
WHERE d.totals IN ( SELECT MAX(s.totals) FROM A s )
ORDER
BY d.mid
, d.totals
The query in the question could also validly return zero rows.
The behavior is due to a MySQL (non-standard) extension. Other databases would balk at that query, returning an error. We can get MySQL to exhibit similar (more standard) behavior by including ONLY_FULL_GROUP_BY in sql_mode, and then MySQL would throw an error 1463.
Reference: https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html

Related

How to insert SUM() function that sums rows with similar ID in a code part of witch is unchangeable?

I am trying to write a quarry in a module for Dolibarr ERP. But module hase a part of code that is predefined and can not be changed. And I need to insert a SUM() function in it that will combine rows with similar id. That i know how to do in a regular MySQL:
SELECT fk_product AS prod, SUM(value) AS qty
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
ORDER BY 1 DESC
LIMIT 26
that gives me what I want :
prod qty
1 13
2 10
BUT module has a predefined unchangeable code :
this part is predefined module writes it himself based on values provider in it:
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
THIS PART I CAN WRITE IN A MODULES GUI:
FROM
llx_stock_mouvement AS c
WHERE
type_mouvement = 2
AND label LIKE 'SH%'
And this part is predefined:
ORDER BY 1 DESC
LIMIT 26
I would appreciate any help and advice on question is there any workaround that can be done to make my desired and result ampere ? As it would using the first code I posted ?
If you can only modify the bit in the middle box then you might need to use a subquery;
--fixed part
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
--begin your editable part
FROM
(
SELECT fk_product,
SUM(value) AS value
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
) c
--end your editable part
--fixed part
ORDER BY 1
DESC
LIMIT 26

Mysql subquery not working properly with comma-separated value in column

I have a MySQL table Mapdetail that has resultTypeIds column storing a comma separated list of ids:
MapDetails
=============================
mapheaderid | resultTypeIds
=============================
54 | 1,4,-9999
Now, when I try it as a subquery, it does not return me the correct result while if I hard-code (1,4,-9999) it works fine
WRONG - RETURNING 1 ROW ONLY
select * from resulttypes rt where rt.resulttypeid in
(select md1.resulttypeids from mapdetail md1
where md1.mapheaderid = 54)
CORRECT - RETURNING 2 ROWS
select * from resulttypes rt where rt.resulttypeid in (1,4,-9999)
If you can't re-structure your DB (as mentioned in Comments). Try using FIND_IN_SET instead of IN
Try something like:
select * from resulttypes rt where FIND_IN_SET (rt.resulttypeid,
(select md1.resulttypeids from mapdetail md1
where md1.mapheaderid = 54))

MySQL MAX from count query

I have table rozpis_riesitelov which contains columns :
id_rozpisu_riesit, id_zam, id_projektu, id_ulohy.
I made query :
select id_zam, id_ulohy, count(*) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)
which shows me id of employee (id_zam) and how many times He was in project (id_ulohy is irrevelant but I had to select it beacuse of having clause). It shows me everyone in db but I am looking for employee with ID of 4 who is in 6 projects (Yes, I could do order by but I want to see max). When I do max of this query like this:
select max(counted)
from (select id_zam, id_ulohy, count(id_zam) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)) as riesitel
which shows me number 149 instead of 6.
So basically I only need to find employee that occurs in the most of the projects.
What's wrong with sorting by the COUNT() value, and limiting to one result?
SELECT `id_zam`,
`id_ulohy`,
COUNT(*) AS `counted`
FROM `rozpis_riesitelov `
WHERE `id_ulohy` IN ( 1, 2, 8 )
GROUP BY `id_zam`
ORDER BY `counted` DESC
LIMIT 1
Not sure exactly what you are trying to accomplish but you only use HAVING to filter on your aggregate like this:
HAVING COUNT(*) > 1
you should be able to move the condition to a WHERE clause and get correct max returned:
select max(counted)
from (select id_zam, count(id_zam) as counted
from rozpis_riesitelov
where id_ulohy in (1,2,8)
group by id_zam) as riesitel

MySQL Table UNION ISSUE

I'm trying to unite two tables in MySQL, the query I'm using is:
SELECT qa_invoicesitems.item_code, qa_invoicesitems.item_unitprice, qa_invoicesitems.item_subtotal, qa_invoicesitems.item_discount,
qa_invoicesitems.item_total
FROM qa_invoicesitems
RIGHT JOIN qa_invoicesitems_returnlog USING (item_code)
WHERE invoice_code = 17
UNION
SELECT qa_invoicesitems_returnlog.item_code, qa_invoicesitems_returnlog.item_unitprice, qa_invoicesitems_returnlog.item_subtotal,
qa_invoicesitems_returnlog.item_discount, qa_invoicesitems_returnlog.item_total
FROM qa_invoicesitems_returnlog
LEFT JOIN qa_invoicesitems USING (item_code)
WHERE returnlog_code = 9
But I can not behold the desired result.
A graphical example ..
Anyone have any idea how I can get this result?
NOTE: qa_invoicesitems_returnlog Replaces the data.
The codes: 1234, 1585, 23 are taken from (qa_invoicesitems_returnlog), because they exist in both tables, the rest are simply displayed.
Based upon your comments & your image, I'm going to say you want:
all the rows in table 2 where qa_invoicesitems_returnlog = 9
all the rows in table 1 where invoice_code = 17, except for those rows w/ item_id's that are already present in the output from table 2.
So, writing that out as a union, give you:
SELECT qa_invoicesitems_returnlog.item_code as item_code,
qa_invoicesitems_returnlog.item_unitprice as item_unitprice,
qa_invoicesitems_returnlog.item_subtotal as item_subtotal,
qa_invoicesitems_returnlog.item_discount as item_discount,
qa_invoicesitems_returnlog.item_total as item_total
FROM qa_invoicesitems_returnlog
WHERE qa_invoicesitems_returnlog.returnlog_code = 9
UNION
SELECT qa_invoicesitems.item_code as item_code,
qa_invoicesitems.item_unitprice as item_unitprice,
qa_invoicesitems.item_subtotal as item_subtotal,
qa_invoicesitems.item_discount as item_discount,
qa_invoicesitems.item_total as item_total
FROM qa_invoicesitems
WHERE qa_invoicesitems.invoice_code = 17
AND NOT EXISTS (SELECT * FROM qa_invoicesitems_returnlog qir2
WHERE qir2.returnlog_code = 9
and qir2.item_code = qa_invoicesitems.item_code)
The key is the NOT EXISTS clause that excludes from the results from table 1 (qa_invoiceitems) that are already present in the output from table 2 and have a matching item_code.
Why are you using a UNION? I think the following is equivalent to your query:
SELECT qa_invoicesitems.item_code, qa_invoicesitems.item_unitprice,
qa_invoicesitems.item_subtotal, qa_invoicesitems.item_discount,
qa_invoicesitems.item_total
FROM qa_invoicesitems RIGHT JOIN
qa_invoicesitems_returnlog
USING (item_code)
WHERE invoice_code = 15 or returnlogcode = 8
The LEFT and RIGHT joins are doing the same thing because the tables are reversed.

mysql select update

Got this:
Table a
ID RelatedBs
1 NULL
2 NULL
Table b
AID ID
1 1
1 2
1 3
2 4
2 5
2 6
Need Table a to have a comma separated list as given in table b. And then table b will become obsolete:
Table a
ID RelatedBs
1 1,2,3
2 4,5,6
This does not rund through all records, but just ad one 'b' to 'table a'
UPDATE a, b
SET relatedbs = CONCAT(relatedbs,',',b.id)
WHERE a.id = b.aid
UPDATE: Thanks, 3 correct answers (marked oldest as answer)! GROUP_CONCAT is the one to use. No need to insert commas between the ids using relatedids = CONCAT(relatedids,',',next_id) that is done automatic by GROUP_CONCAT.
You'll have to use the mysql group_concat function in order to achieve this: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_group-concat
Look into GROUP_CONCAT(expr)
mysql> SELECT student_name,
-> GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR " ")
-> FROM student
-> GROUP BY student_name;
You can't do that in standard SQL. You could write a stored procedure to do that. I had a similar problem, but I was using PostgreSQL so I was able to resolve it by writing a custom aggregate function so that you can do queries like
select aid, concat(id)
from b group by
aid
Update: MySQL has a group_concat aggregate function so you can do something like
SELECT id,GROUP_CONCAT(client_id) FROM services WHERE id = 3 GROUP BY id
as outlined here.