Mysql query to find sum of fields with same column value - mysql

I have a table like this
id | invent_id | order
1 | 95948214 | 70
2 | 46018572 | 30
3 | 46018572 | 20
4 | 46018572 | 50
5 | 36025764 | 60
6 | 36025764 | 70
7 | 95948214 | 80
8 | 95948214 | 90
I want get the sum of order qty with same invent id
That is the want the result like this
| invent_id | order
| 95948214 | 240
| 46018572 | 100
| 36025764 | 130
how can we write the mysql query

Make use of Aggregate function SUM and grouped them according to invent_id.
SELECT invent_id, SUM(`order`) `Order`
FROM tableName
GROUP BY invent_ID
GROUP BY clause
SQLFiddle Demo

Related

Cross join with aggregate greatest value

I have the following table, let's call it Segments:
-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1 | 4 | 20 |
| 4 | 8 | 60 |
| 8 | 10 | 20 |
| 10 | 1000000 | 0 |
-------------------------------------
I am trying to join this table with itself, to obtain the following result set:
-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1 | 4 | 20 |
| 1 | 8 | 60 |
| 1 | 10 | 60 |
| 1 | 1000000 | 60 |
| 4 | 8 | 60 |
| 4 | 10 | 60 |
| 4 | 1000000 | 60 |
| 8 | 10 | 20 |
| 8 | 1000000 | 20 |
| 10 | 1000000 | 0 |
-------------------------------------
Basically, I would need to join every row, with every other row that comes after it, then get the MAX() of the value between each of the rows joined previously. Example: if I am joining row 1 with row 3, I would need the MAX(Value) from all of these 3 rows.
What I already done is the following query:
SELECT s1.SegmentStart, s2.SegmentEnd, GREATEST(s1.Value, s2.Value) as Value FROM Segments s1 CROSS JOIN Segments s2 ON s1.SegmentStart < s2.SegmentEnd
This query creates a similar table to the one desired, but the value fields get mixed up in the following way (I've marked between !! the row that differs):
-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1 | 4 | 20 |
| 1 | 8 | 60 |
| 1 | 10 | !20! |
| 1 | 1000000 | !20! |
| 4 | 8 | 60 |
| 4 | 10 | 60 |
| 4 | 1000000 | 60 |
| 8 | 10 | 20 |
| 8 | 1000000 | 20 |
| 10 | 1000000 | 0 |
-------------------------------------
The problem is with the GREATEST() function, because it only compares the two rows that are being joined (start-end 1-4, 8-10), and not the whole interval (in this case, it would be 3 rows, the ones with start-end 1-4, 4-8, 8-10)
How should I modify this query, or what query should I use, to get my desired result?
Additional info, that may help: the rows in the original table, are always ordered based on SegmentStart, and there can be no duplicate or missing values. Every interval between x and y will appear only once in the table, with no overlaps, and no gaps at all.
I am using Maria DB 10.3.13.
Something like this?
SELECT
s1.SegmentStart
, s2.SegmentEnd
, MAX(s.Value) as Value
FROM
Segments s1
INNER JOIN Segments s2 ON (
s2.SegmentEnd > s1.SegmentStart
)
INNER JOIN Segments s ON (
s.SegmentStart >= s1.SegmentStart
AND s.SegmentEnd <= s2.SegmentEnd
)
GROUP BY
s1.SegmentStart
, s2.SegmentEnd

return a unique list from query result after removing duplicate rows from the table

I have two columns product_id, r_store_id which have a few rows with same values. Rest of the column rows have different values
I have duplicate rows with same r_store_id and product_id because every time I have to add new entries into this table. I want unique rows list with latest update_dt
(refer the DB table below).
id | m_store_id |r_store_id|product_id | amount |update_dt |
1 | 4 | 1 | 45 | 10 |18/03/5 |
2 | 4 | 1 | 45 | 100 |18/03/9 |
3 | 4 | 1 | 45 | 20 |18/03/4 |
4 | 5 | 2 | 49 | 10 |18/03/8 |
5 | 5 | 2 | 49 | 60 |18/03/2 |
6 | 9 | 3 | 45 | 19 |18/03/5 |
7 | 9 | 3 | 45 | 56 |18/03/3 |
My result should look like this:
id | m_store_id |r_store_id|product_id | amount |update_dt |
2 | 7 | 1 | 45 | 100 |18/03/9 |
4 | 5 | 2 | 49 | 10 |18/03/8 |
6 | 9 | 3 | 45 | 19 |18/03/5 |
I want to put this result in a list like this:
List<Sales> salesList = (List<Sales>) query.list();
I am not able to find an easy solution. Please help me with this!
We can select the chronologically most recent update for each store, and then join to get all the variables:
select a.*
from mytable a
join (select m_store_id, r_store_id, product_id, max(update_dt) as maxdate
from mytable
group by 1,2,3) b
on a.m_store_id=b.m_store_id
and a.r_store_id=b.r_store_id
and a.product_id=b.product_id
and a.update_dt = b.maxdate;

Getting a total from multiple rows in MySQL

I am not very good at MySQL queries. Can someone help me figure out how to do this?
I have a table like this (lets call it stats):
+----+-------+-----+
| id | memid | qty |
+----+-------+-----+
| 1 | 99 | 0 |
+----+-------+-----+
| 2 | 102 | 22 |
+----+-------+-----+
| 3 | 102 | 10 |
+----+-------+-----+
| 4 | 99 | 100 |
+----+-------+-----+
| 5 | 17 | 25 |
+----+-------+-----+
| 6 | 87 | 72 |
+----+-------+-----+
| 7 | 36 | 0 |
+----+-------+-----+
| 8 | 102 | 6 |
+----+-------+-----+
I need a MySQL query that will combine the qty of all the memids and ORDER BY ASC the total qty for each memid.
Thank you in advance for your help! :)
You can select SUM as another field in query and order it by qty, e.g.:
SELECT id, memid, qty, SUM(qty)
FROM table
ORDER BY qty;
Please note that SUM will return the same value for all the rows as it will be a constant value.
If you have multiple records per memid and want to calculate SUM per memid then you can use GROUP BY e.g.:
SELECT memid, SUM(qty) AS `sum`
FROM table
GROUP BY memid
ORDER BY sum;

need help a query in sql server 2008

Hi I have doubt in sql server
Table : patient
patientno | refdoctor| loccode | status | sdate
100 | 31 |10 | 1 | 2012-05-03
100 | 32 |10 | 1 |1997-02-04
100 | 36 |10 | 1 |2014-09-16
100 |35 |10 | 1 |2013-05-03
100 | 50 |10 | 1 | 1988-05-08
100 | 20 |10 | 2 |2015-02-05
Table : targetpatient
patientno | refdoctor| loccode | status | sdate
100 | 21 | 10 | 2 | 2004-05-18
100 | 23 | 10 | 2 |2005-07-25
100 | 24 | 10 | 2 | 2006-06-22
100 | 26 | 10 | 2 |2012-05-14
100 | 28 |10 | 2 |2013-05-03
100 |29 |10 | 2 | 2014-09-26
100 | 33 | 10 | 2 | 2012-10-22
100 | 39 | 10 | 2 |2002-12-13
100 |41 | 10 | 2 |2012-05-13
Here I want output patient table relates status
statusvalue=5's sdate is less than or equal to checkvalue=2's sdate and
the difference between the dates should be less than 30days then given count
if that condition not fall then count must be return zero(0)
select o.patientno,o.loccode,o.status,o.sDate, count(*) as cnt
from patient o join targetpatient t on o.patientno=t.patientno and o.loccode=t.loccode and o.status in('1') and t.status in('2') and
o.sDate<=t.sdate
and datediff(dd,o.sdate,t.sdate)<=30
group by o.patientno,o.loccode,o.status,o.sDate
based on above query I got result like below:
patientno | loccode | status | sdate | count
100 | 10 | 1 |2012-05-03 | 2
100 | 10 | 1 |2013-05-03 | 1
100 | 10 | 1 |2014-09-16 | 1
but I want expected result like below
patientno | loccode | status | sdate | count
100 | 10 | 1 |2012-05-03 | 2
100 | 10 | 1 |2013-05-03 | 1
100 | 10 | 1 |2014-09-16 | 1
100 | 10 | 1 | 1997-02-04 | 0
100 | 10 |1 | 1988-05-08 | 0
please tell me how to write query to achive this task in sql server .
If you want to include the records that doesn't have any matches in the joined table you'll want to use a left join instead and do the count on a column in the joined table instead like this:
select o.patientno,o.loccode,o.status,o.sDate, count(t.sdate) as cnt
from patient o
left join targetpatient t on o.patientno = t.patientno
and o.loccode = t.loccode
and o.status in('1')
and t.status in('2')
and o.sDate <= t.sdate
and datediff(dd,o.sdate,t.sdate) <= 30
group by o.patientno,o.loccode,o.status,o.sDate
A left join will return all rows from the table on the left side (patient in your case) plus the matching rows from the right-hand side table. The rows that doesn't have any matches in the right-hand side table will get null as values.

count records by grouping of two columns

I am trying to count how many variations of amount there are per fk_id. If there is more than one variation then I want the record to be returned otherwise I want the record to be ignored.
What is wrong with the below statement?
SELECT *, count(fk_id) AS `count` FROM table
WHERE count > 1
GROUP BY fk_id, amount;
Table:
+-----------+----------+--------------+
| id | fk_id | amount |
+-----------+----------+--------------+
| 1 | 100 | 5 |
| 2 | 200 | 10 |
| 3 | 200 | 10 |
| 4 | 200 | 10 |
| 5 | 200 | 15 |
+-----------+----------+--------------+
Expected output:
+-----------+----------+--------------+--------------+
| id | fk_id | amount | count |
+-----------+----------+--------------+--------------+
| 2 | 200 | 10 | 2 |
+-----------+----------+--------------+--------------+
You cannot use an aggregate function in WHERE clause. Use HAVING clause instead:
SELECT MIN(id) as id,fk_id,amount, count(fk_id)-1 AS `count`
FROM table
GROUP BY fk_id, amount
HAVING count(fk_id)>1
Result:
ID FK_ID AMOUNT COUNT
2 200 10 2
See result in SQL Fiddle.