How to get order and sum between three tables on mysql? - mysql

I'm trying to sort table 1 using the sort on table 2
and sum the value for each "order number" on table 1 and group by "order number"
and after that bring the client name from table 3 then the result should be like that:
sort ordernumber sumvalue name location
01 5555 120 Client 2 location 2
01 5498 50 Client 2 location 2
02 2324 50 Client 1 location1
02 4356 30 Client 1 location1
tables:
table 1 orders
===============
id ordernumber code_client value
1 2324 01 20
1 2324 01 30
1 4356 01 30
1 5555 02 40
1 5555 02 40
1 5498 02 50
1 5555 02 40
table 2 sort
============
sort code_client
1 02
2 01
table 3 client
===============
code_client name location
01 Client 1 location1
02 Client 2 location2
what i done in the following code is not respect the order even the sum for each ordernumber
SELECT orders.ordernumber,
SUM(orders.value) AS totalordersvalue,
orders.code_client,
sort.code_client,sort.sort,
client.code_client,client.name, client.location,
FROM orders
LEFT JOIN client
ON client.code_client = orders.code_client
LEFT JOIN sort
ON sort.code_client = orders.code_client
WHERE orders.id = 1
GROUP BY orders.ordernumber
ORDER BY sort.sort
there is any way to get the correct order and correct sum for each order as the final result ? thanks

You can try below -
select sort, ordernumber ,totalordersvalue as sumvalue,name,location from
(
SELECT orders.ordernumber, SUM(orders.value) AS totalordersvalue,
orders.code_client
FROM orders WHERE orders.id = 1 group by orders.ordernumber,orders.code_client
)A inner join client ON client.code_client = A.code_client
inner join sort ON sort.code_client = A.code_client
ORDER BY sort.sort

If the sequence of getting a result doesn't matter for you then you can use the following query
SELECT
DISTINCT o.ordernumber,
s.sort,
(SELECT sum(os.value) AS sum_value FROM orders AS os WHERE o.ordernumber =
os.ordernumber GROUP BY os.ordernumber) AS sum_value,
c.name,
c.location
FROM
sort AS s,
orders AS o,
client AS c
WHERE c.code_client = o.code_client AND o.code_client=s.code_client
ORDER BY s.sort;
Output:
ordernumber sort sumvalue name location
5555 01 120 Client 2 location 2
5498 01 50 Client 2 location 2
2324 02 50 Client 1 location1
4356 02 30 Client 1 location1

Related

How to join to single row in one to many relationship in SQL?

I want to join one to many table with single row on many table by limit 1 and order by create date
tbl_cart :
id fullname
1 myname1
2 myname2
3 myname3
tbl_cart_status:
id cart_id status created_at
1 1 33 2018-09-20
2 1 34 2018-09-23
3 2 34 2018-09-21
4 1 100 2018-09-25
5 2 35 2018-09-29
How can i get output with sql like this:
I want to get lastest status of my cart by ordered with created_at column
myname cart_id status created_at
myname1 1 100 2018-09-25
myname2 2 35 2018-09-29
Think filtering for this type of query:
select c.name, cs.*
from tbl_cart c join
tbl_cart_status cs
on c.id = cs.cart_id
where cs.created_at = (select max(cs2.created_at)
from tbl_cart_status cs2
where cs2.cart_id = cs.cart_id
);

MySQL get the latest products with distinct product_name from a particular month

I've the following product table in my database. I want to get the rows of all the products with distinct product_name added in the month of Dec in the descending order of their id.
id product_name qty month
1 Apple 20 Dec
2 Banana 40 Jan
3 Cherry 60 Jun
4 Apple 25 Dec
5 Banana 50 Dec
6 Papaya 20 Dec
7 Guava 34 Aug
8 Watermelon 55 Mar
9 Apple 75 Dec
10 Orange 32 Dec
The resulting table should be as below:
id product_name qty month
10 Orange 32 Dec
9 Apple 75 Dec
6 Papaya 20 Dec
5 Banana 50 Dec
So far I've come up with the following query and it doesn't get the result I need.
SELECT *
FROM product
WHERE month = "Dec"
GROUP BY product_name
ORDER BY id DESC
The problem with this query is that it gets the first row/record of Apple rather than last one as shown in table below:
id product_name qty month
10 Orange 32 Dec
6 Papaya 20 Dec
5 Banana 50 Dec
1 Apple 20 Dec
Can anyone help me write a proper mysql query for this?
You can use the following query:
SELECT MAX(id), product_name
FROM product
WHERE month = "Dec"
GROUP BY product_name
to get the biggest id per product_name:
Output:
max_id product_name
9 Apple
5 Banana
10 Orange
6 Papaya
Using the above query as a derived table you can join back to the original table in order to get the rest of the fields:
SELECT t1.*
FROM product AS t1
INNER JOIN (
SELECT MAX(id) AS max_id, product_name
FROM product
WHERE month = "Dec"
GROUP BY product_name
) AS t2 ON t1.id = t2.max_id and t1.product_name = t2.product_name
ORDER BY t1.id
Demo here

Count unique values from duplicates

I have following data on the table.
Uid | comm | status
-------------------
12 23 eve
15 23 eve
20 23 mon
12 23 mon
20 23 eve
17 23 mon
how do i query to get below result to avoid duplicates and make sure if i count uid for "eve" and same uid appears on "mon" then count only uid for "eve"?
count | status
-------------------
3 eve
1 mon
Thanks for the help!
You can use the following query in order to pick each Uid value once:
SELECT Uid, MIN(status)
FROM mytable
GROUP BY Uid
Output:
Uid MIN(status)
---------------
12 eve
15 eve
17 mon
20 eve
Using the above query you can get at the desired result like this:
SELECT status, count(*)
from (
SELECT Uid, MIN(status) AS status
FROM mytable
GROUP BY Uid ) AS t
GROUP BY status
Demo here

select data based on multiple criteria (cloest value)

I am using MySQL. I'm trying to build something and just can't find a solution to a problem.
I am selecting a value from the lookup table based on my table as shown in the below example.
Select Criteria:
my.id<>l.id AND my.route1=l.route1 AND my.route2=l.route2 AND my.utc=l.utc
where my.stime is closest or same as l.stime
ex) my.id=2's col should get the l.id=1, l.etime=7777 since my.id<>l.id and the rest are the same.
ex) my,id=5's col has options l.id=3, l.etime=9999 and l.id=4, l.etime=7979 since my.id<>l.id, my.route=l.route, my.utc=l.utc. Yet, since my.stime=2220 is closer to l.stime=2222 than l.stime=3333 , l.id=3, l.etime=9999 will be chosen.
ex) my,id=6's col example is to select either value if "closest" is the same.
ex) my,id=7's col example is to return NULL when the criteria is not met.
Table: lookup (l.)
id route1 route2 utc stime etime
---|--------|--------|-----|-------|------
1 11 22 111 1111 7777
2 11 22 111 1111 8888
3 22 33 222 2222 9999
4 22 33 222 3333 7979
5 22 33 222 3335 8989
Table: my (my.) | result
id route1 route2 utc stime | l.id l.etime
---|--------|--------|-----|------- |-------|----------|
2 11 22 111 1111 | 1 7777
5 22 33 222 2220 | 3 9999
6 22 33 222 3334 | 4or5 7979or8989
7 22 33 999 9999 | null null
A new table should be created where the result is appended to the last col of my.
Any help is appreciated. Thanks in advance.
This solution is a bit convoluted, but it's a starting point.
First, let's create an auxiliary table:
CREATE TEMP TABLE temp AS
SELECT m.id mid, l.id lid, ABS(l.stime-m.stime) timediff
FROM my m JOIN lookup l
WHERE m.route1 = l.route1 AND m.route2 = l.route2 AND
m.utc = l.utc AND m.id <> l.id;
From this table we can get the minimum timediff for each my.id:
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
Result:
mid mtimediff
---------- ----------
2 0
5 2
6 1
Now we can find which rows in lookup have this stime difference, and choose the smallest id:
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
This is the result:
mid lid
---------- ----------
2 1
5 3
6 4
And finally we use those ids to extract the data from the tables:
SELECT m.id, m.route1, m.route2, m.utc, m.stime, l.id, l.etime
FROM my m JOIN lookup l JOIN (
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
) ON m.id = mid AND l.id = lid;
Giving:
id route1 route2 utc stime id etime
---------- ---------- ---------- ---------- ---------- ---------- ----------
2 11 22 111 1111 1 7777
5 22 33 222 2220 3 9999
6 22 33 222 3334 4 7979

Select up to x rows of each group

With a table of:
id | name | job | rank
01 john teacher 4
02 mark teacher 2
03 phil plummer 1
04 dave teacher 7
05 jim plummer 9
06 bill plummer 2
How can I select up to 2 rows of each job (if possible sorted by rank ASC in each group, so that the lowest two ranking of each group get picked). The result I'd be looking for is:
02 mark teacher 2
01 john teacher 4
03 phil plummer 1
06 bill plummer 2
This basically groups by job, with a limit to 2 and sorted by rank. I've been trying with GROUP BY as well as LEFT JOIN, but I just can't figure out how to do this. When creating a "temporary list" of jobs with GROUPING BY job, how do I join more than once onto that job?
SELECT id, name, job, rank
FROM TableName a
WHERE
(
SELECT COUNT(*)
FROM TableName as f
WHERE f.job = a.job AND
f.rank <= a.rank
) <= 2;
SQLFiddle Demo