replace a value for grouped rows only - mysql

I have the following sample data:
Date
amount
type
grouping_value
2021-03-01
10
1
2021-03-04
15
3
2021-03-16
32
4
2021-03-16
1
2
a
2021-03-16
4
3
a
2021-03-16
48
4
a
and my expected result is:
Date
amount
type
grouping_value
2021-03-01
10
1
2021-03-04
15
3
2021-03-16
32
4
2021-03-16
53
9
a
with the following query:
SELECT date, SUM(amount), type, grouping_value
FROM table
GROUP BY date, grouping_value
The query is still untested but should work for all requirements but one.
As you can see from the results, the query should group by date and grouping_value. So the first three rows of my input data will remain as they are, the other three will be grouped in one movement. What I want to do is: when some rows are grouped show 9 as type instead of one of the types that are grouped. If a row is not grouped then show the original type.
The condition to group is that grouping_value is not blank.
How can I tell mysql to replace if it is grouping only?

Use COUNT(*) to tell if the row is in a group.
SELECT date, SUM(amount), IF(COUNT(*) > 1, 9, MAX(type)) AS type, grouping_value
FROM table
GROUP BY date, grouping_value

Related

MySQL Group by consecutive values and count

I have a table that looks like this
id
1
2
4
5
6
10
11
So a bunch of consecutive values, an unknown number of absent fields and then other consecutive values.
What I am trying to achieve is to get
id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
By incrementing every time the number of the stint, which I can later use for summing over other columns.
Is it possible? Thanks
If your MySQL version support window function.
You can try to use LAG window function in subquery to get previous id column, then use SUM condition aggregate window function.
Query #1
SELECT Id,
SUM(id - n_Id > 1) OVER(ORDER BY id) stint
FROM (
SELECT *,LAG(id,1,id) OVER(ORDER BY id) n_Id
FROM T
) t1
Id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
View on DB Fiddle

How to show all MIN of SUM(column) that has the same min value?

I've been trying to get MIN of SUM of a column by doing subqueries, however in a case where I have two same SUM values, my query only returns me one of them. Is there a way to get all of them to be shown?
So for example this table is called quantity,
date product_id quantity_start quantity_end
1/1/2020 1 10 5
1/1/2020 2 10 5
1/1/2020 3 12 1
2/2/2020 1 10 5
2/2/2020 2 11 6
2/2/2020 3 14 1
my query would be
SELECT product_id, MIN(Total) as Minimum
FROM (SELECT product_id, SUM(quantity_start - quantity_end) as Total
FROM quantity
GROUP BY product_id)T
But this will return me only one min value while there are two since both product 1 and 2 will have total of 10 from my subquery. Is there a way to write it such that it shows me both ?
Thanks!
You are correctly grouping by your sub query, but the outer query also needs a group by so:
SELECT product_id, MIN(Total) as Minimum
FROM (SELECT product_id, SUM(quantity_start - quantity_end) as Total
FROM quantity
GROUP BY product_id)T
GROUP BY product_id;
See it working here: http://sqlfiddle.com/#!9/97d7724/1

mysql group by day and count then filter only the highest value for each day

I'm stuck on this query. I need to do a group by date, card_id and only show the highest hits. I have this data:
date card_name card_id hits
29/02/2016 Paul Stanley 1345 12
29/02/2016 Phil Anselmo 1347 16
25/02/2016 Dave Mustaine 1349 10
25/02/2016 Ozzy 1351 17
23/02/2016 Jhonny Cash 1353 13
23/02/2016 Elvis 1355 15
20/02/2016 James Hethfield 1357 9
20/02/2016 Max Cavalera 1359 12
My query at the moment
SELECT DATE(card.create_date) `day`, `name`,card_model_id, count(1) hits
FROM card
Join card_model ON card.card_model_id = card_model.id
WHERE DATE(card.create_date) >= DATE(DATE_SUB(NOW(), INTERVAL 1 MONTH)) AND card_model.preview = 0
GROUP BY `day`, card_model_id
;
I want to group by date, card_id and filter the higher hits result showing only one row per date. As if I run a max(hits) with group by but I won't work
Like:
date card_name card_id hits
29/02/2016 Phil Anselmo 1347 16
25/02/2016 Ozzy 1351 17
23/02/2016 Elvis 1355 15
20/02/2016 Max Cavalera 1359 12
Any light on that will be appreciated. Thanks for reading.
Here is one way to do this. Based on your sample data (not the query):
select s.*
from sample s
where s.hits = (select max(s2.hits)
from sample s2
where date(s2.date) = date(s.date)
);
Your attempted query seems to have no relationship to the sample data, so it is unclear how to incorporate those tables (the attempted query has different columns and two tables).

Replacement of correlated query

I have table with name orders:
id id_o value date
1 1 400 2014-09-30
2 1 300 2014-09-30
3 1 200 2014-09-30
4 2 100 2014-09-30
5 2 200 2014-09-30
6 3 50 2014-09-29
7 3 100 2014-09-29
8 4 300 2014-09-29
9 5 600 2014-09-28
I need select every order grouped by id_o with sum(value)< 700 and from this selected table i need display data grouped by datum.
I use multiple select:
select date, sum(mno) as mn
from (
select date,sum(value) as 'mno'
from orders
group by id_o
having sum(value)<700
) table_alias
group by date
This is result:
date mn
2014-09-30 300
2014-09-29 450
2014-09-28 600
Is there any possibility to replace or to simplify this correlated query?
Your inner query is invalid. It groups by id_o, but selects by date. In order to solve this, add an additional column to the inner queries grouping (assuming date is always the same for every id_o). You can enable strong checking by enabling the sql_mode's ONLY_FULL_GROUP_BY. Full example in SQL fiddle.
SELECT
date,
SUM(mno) AS mn
FROM (
SELECT
id_o,
date,
SUM(value) AS mno
FROM orders
GROUP BY
id_o,
date
HAVING
SUM(value) < 700
) totalPerOrder
GROUP BY date
MySQL allows this type of queries, but it's not common to do so. Consider the following data:
id id_o value date
1 1 400 2014-09-29
2 1 300 2014-09-30
3 1 200 2014-09-30
What date(s) would SELECT date, SUM(value) FROM orders GROUP BY id_o return? It could be the first, last, average, most common one, but better make it explicit. Any other DBMS wouldn't let you execute this query.
Other than that, I would rename some of the columns to be more expressive. mn, mn_o and id_o are examples of this. Also value describes nothing, anything can be a value. Even the date field could have been called value. The query itself seems fine (take care if possibly missing indexes though).

How may i group this data in mysql

I Have a table called
CountryVisits
Visitor Date
4 20/12/12 14:27:7
5 20/12/12 15:45:11
6 20/12/12 16:36:51
12 21/12/12 11:17:2
145 21/12/12 12:37:57
445 21/12/12 13:35:15
435 21/12/12 14:34:35
I want to have a count of all visitors per Date not time :
So i expect :
VisitorCnt Date
3 20/12/12
4 21/12/12
I tried :
SELECT COUNT(DATE(Date)), DATE(Date) from CountryVisits GROUP BY Date ;
But i don't have the desired results.
When you write GROUP BY Date it's grouping by the Date column in the table, which includes times. If you want to group by just the day, you need to assign an alias and group by that:
SELECT COUNT(*), DATE(Date) AS VisitedOn
FROM CountryVisits
GROUP BY VisitedOn