SQL how to group all results based on joining tables - mysql

I need Help Joining table that record transaction, market transactions, and station transactions.
I want to get results based on the location, the station transaction table gets its location from the joining table.
Tables are as follow :
market_transations
+------------------------------------------------------------------+---------------------+
| m_trans_id | markeeter_id | amount | receipt | loction_id | trans_date |
+-------------+---------------+---------+----------+---------------+---------------------+
| 1 + 1 | 20 | abc123 | 1 | 2020-09-16 23:20:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
| 2 + 2 | 20 | xcv897 | 1 | 2020-09-18 09:00:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
| 3 + 6 | 10 | qwe563 | 3 | 2020-09-19 12:00:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
station_transactions
+------------------------------------------------------------------+---------------------+
| s_trans_id | draver_id | amount | receipt | station_id | trans_date |
+-------------+---------------+---------+----------+---------------+---------------------+
| 1 + 1 | 5 | 123456 | 1 | 2020-09-16 13:20:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
| 2 + 2 | 50 | qwerty | 2 | 2020-09-17 09:00:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
| 3 + 6 | 10 | zxcvbn | 3 | 2020-09-18 11:00:00 |
+-------------+---------------+---------+----------+---------------+---------------------+
locations
----------+-----------+
| id | name |
+---------+-----------+
| 1 | a |
+---------+-----------+
| 2 | b |
+---------+-----------+
| 3 | c |
+---------+-----------+
| 4 | d |
+---------+-----------+
stations
---------+---------+-------------+
| id | name | loctaion_id |
+--------+---------+-------------+
| 1 | st1 | 1 |
+--------+---------+-------------+
| 1 | st2 | 2 |
+--------+---------+-------------+
| 1 | st3 | 3 |
+--------+---------+-------------+
Expected Result
-------------------+-----------+---------------+---------+----------+-----------------------+
| location_name | driver_id | markeeter_id | amount | receipt | trans_date |
+------------------+-----------+---------------+---------+----------+-----------------------+
| a | 1 | NULL | 5 | 123456 | 2020-09-16 13:20:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+
| a | NULL | 1 | 20 | abc123 | 2020-09-16 23:20:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+
| b | 2 | NULL | 50 | qwerty | 2020-09-17 09:00:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+
| c | 6 | NULL | 10 | zxcvbn | 2020-09-18 11:00:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+
| a | NULL | 2 | 20 | xcv897 | 2020-09-18 09:00:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+
| c | NULL | 3 | 10 | qwe563 | 2020-09-19 12:00:00 |
+------------------+-----------+---------------+---------+----------+-----------------------+

While I couldn't test the query this should the job
SELECT l.name AS location_name, NULL as driver_id, mt.markeeter_id, mt.amount, mt.receipt, mt.trans_date
FROM market_transations mt, locations l
WHERE l.id = mt.location_id
UNION
SELECT l.name AS location_name, st.driver_id, NULL AS markeeter_id, st.amount, st.receipt, st.trans_date
FROM station_transactions st, stations s, locations l
WHERE st.station_id = s.id AND s.location_id l.id

SELECT locations.name as name ,driver_id,NULL as markeeter_id,st.amount as amount, st.receipt as receipt, st.trans_date as trans_date FROM locations
JOIN stations ON locations.id = station.location_id
JOIN station_transactions st ON station.id = st.station_id
order by trans_date ASC
UNION
SELECT locations.name as name ,NULL as driver_id,markeeter_id,mt.amount as amount, mt.receipt as receipt, mt.trans_date as trans_date FROM locations
JOIN market_tramlsactop mt ON locations.id = mt.location_id
order by trans_date ASC

Related

how do i use group by in only one row?

Correct me if the question title is wrong ,
i have table in MySQL Named sales
-------------------------------------------------------------------------------------
| PRODUCT_NAME | PRODUCT_QUANTITY | PRODUCT_TYPE | In_Box_Count_Sell | ExpiryDate |
-------------------------------------------------------------------------------------
| kkkkk | 4 | Count | 1 | 2021-02-28 |
| kkkkk | 4 | Count | 1 | 2021-02-21 |
| yuyuyu | 3 | Count | 5 | 2021-02-21 |
-------------------------------------------------------------------------------------
Another Table Named depot
--------------------------------
| ITEM_NAME | PRODUCT_QUANTITY |
--------------------------------
| kkkkk | 12 |
| yuyuyu | 15 |
--------------------------------
I have used this query :
SELECT `ExpiryDate`,`PRODUCT_NAME` As pdname,sales.`PRODUCT_QUANTITY`,`In_Box_Count_Sell`,`PRODUCT_TYPE`,(`depot`.`PRODUCT_QUANTITY`) As InDepotQuent FROM ((`sales`
INNER JOIN depot ON sales.PRODUCT_NAME = depot.ITEM_NAME)
INNER JOIN bill_info ON sales.BILL_NUMBER = bill_info.BILL_NUMBER)
WHERE bill_info.BILL_TYPE = 'مشتريات'
ORDER BY `sales`.`PRODUCT_NAME` ASC
And its result is :
---------------------------------------------------------------------------------------------
| ExpiryDate | pdname | PRODUCT_QUANTITY | In_Box_Count_Sell | PRODUCT_TYPE | InDepotQuent |
---------------------------------------------------------------------------------------------
| 2021-02-21 | kkkkk | 10 | 1 | Count | 12 |
| 2021-02-28 | kkkkk | 4 | 1 | Count | 12 |
| 2021-08-25 | yuyuy | 3 | 5 | Count | 15 |
---------------------------------------------------------------------------------------------
what i need to get is the atc = the sum of PRODUCT_QUANTITY - the sum of InDepotQuent and the result will be like this :
---------------------------------------------------------------------------------------------------
| ExpiryDate | pdname | PRODUCT_QUANTITY | In_Box_Count_Sell | PRODUCT_TYPE | InDepotQuent | atc |
---------------------------------------------------------------------------------------------------
| 2021-02-21 | kkkkk | 10 | 1 | Count | 12 | 2 |
| 2021-02-28 | kkkkk | 4 | 1 | Count | 12 | 2 |
| 2021-08-25 | yuyuy | 3 | 5 | Count | 15 | 12 |
---------------------------------------------------------------------------------------------------
So the sum of PRODUCT_QUANTITY = (14) - sum of InDepotQuent = (12)
The atc = 2
And taking into account the name of the pdname are similar in a table !
You can use window functions, if I understand correctly:
SELECT ExpierDate, PRODUCT_NAME As pdname, s.PRODUCT_QUANTITY,
In_Box_Count_Sell, PRODUCT_TIPE, d.PRODUCT_QUANTITY As InDepotQuent,
SUM(s.PRODUCT_QUANTITY) OVER (PARTITION BY PRODUCT_NAME) - d.PRODUCT_QUANTITY as atc
FROM sales s JOIN
depot d
ON s.PRODUCT_NAME = d.ITEM_NAME JOIN
bill_info bi
ON s.BILL_NUMBER = bi.BILL_NUMBER
WHERE bi.BILL_TIPE = 'مشتريات'
ORDER BY s.PRODUCT_NAME ASC;

MySQL table value difference related to current date and previous date

I have some tables that used to manage vehicle details. Related tables as follows:
store_item
+---------+-----------+--------+
| item_id | item_name | status |
+---------+-----------+--------+
| 1 | Diesel | 1 |
| 2 | Petrol | 1 |
+---------+-----------+--------+
tbl_vehicle
+------------+---------------+
| vehicle_id | registered_no |
+------------+---------------+
| 1 | LE-7476 |
| 2 | 270-0523 |
+------------+---------------+
tbl_direct_fuel
+----------------+----------+---------+------------+------------+
| direct_fuel_id | vehicle | orderNo | issue_date | milo_meter |
+----------------+----------+---------+------------+------------+
| 1 | LE-7476 | 173072 | 2019-11-12 | 30,000 |
| 2 | LE-7476 | 173069 | 2019-11-08 | 29,600 |
| 3 | LE-7476 | 173059 | 2019-11-05 | 29,000 |
| 4 | LE-7476 | 173055 | 2019-10-08 | 25,000 |
| 5 | 270-0523 | 173068 | 2019-11-02 | 10,000 |
| 6 | 270-0523 | 173067 | 2019-10-02 | 8,500 |
+----------------+----------+---------+------------+------------+
tbl_direct_fuel_details
+------------------------+----------------+------+----------+------------+
| direct_fuel_details_id | direct_fuel_id | item | fuel_qty | fuel_price |
+------------------------+----------------+------+----------+------------+
| 100 | 1 | 1 | 20 | 105 |
| 101 | 2 | 1 | 15 | 105 |
| 102 | 3 | 1 | 12 | 105 |
| 103 | 4 | 2 | 50 | 165 |
| 104 | 5 | 1 | 25 | 100 |
| 105 | 6 | 2 | 18 | 165 |
+------------------------+----------------+------+----------+------------+
Desired Output
I want to get no_of_kms, vs issued fuel quantities using issue_date & milo_meter (current milo_meter - previous milo_meter). The output as follows :
+----------+-----------+
| vehicle | no_of_kms |
+----------+-----------+
| LE-7476 | 400 |
| LE-7476 | 600 |
| LE-7476 | 4,000 |
| 270-0523 | 1500 |
+----------+-----------+
I used the following query :
select v1.registered_no as vehicle, si.item_name as fuel, df.milo_meter - df.milo_meter as no_of_kms
from (select dfd.item, sum(dfd.fuel_qty) AS qty
from tbl_direct_fuel df
join tbl_direct_fuel_details dfd on df.direct_fuel_id = dfd.direct_fuel_id
join tbl_vehicle v1 on df.vehicle = v1.vehicle_id
where df.status = 1
group by registered_no) dfd
join store_item si on dfd.item = si.item_id
join (select item, sum(dfd.fuel_qty) AS fuel_qty
from tbl_direct_fuel_details
group by item) dfd on si.item_id=dfd.item
But the above query didn't working fine. What may be going wrong ? Can anyone help me ?
If you are running MySQL 8.0, you can do this simply with window function lag():
select *
from (
select
issue_date,
vehicle,
milo_meter
- lag(milo_meter) over(partition by vehicle order by issue_date) no_of_kms
from tbl_direct_fuel
) t
where no_of_kms is not null
order by vehicle desc, issue_date desc
I added the issue_date to the output columns, since this seems like a sensible information to understand the results.
In earlier versions, I think that an inline query might do the trick:
select *
from (
select
issue_date,
vehicle,
milo_meter - (
select max(milo_meter)
from tbl_direct_fuel d1
where d1.vehicle = d.vehicle and d1.issue_date < d.issue_date
) no_of_kms
from tbl_direct_fuel d
) t
where no_of_kms is not null
order by vehicle desc, issue_date desc
This assumes that the milo_meter of a given vehicule can only increase, which seems like a reasonable assumption.
Demo on DB Fiddle
Both queries return:
issue_date | vehicle | no_of_kms
:--------- | :------- | --------:
2019-11-12 | LE-7476 | 400
2019-11-08 | LE-7476 | 600
2019-11-05 | LE-7476 | 4000
2019-11-02 | 270-0523 | 1500

sql joins with multiple conditions

i have two tables, (say bill and soldproduct)
select * from bill;
+------+------------+------------+
| id | solddate | customerId |
+------+------------+------------+
| 11 | 2018-07-23 | 1 |
| 12 | 2018-07-21 | 1 |
| 13 | 2018-08-02 | 2 |
| 14 | 2018-08-08 | 2 |
| 15 | 2018-08-08 | 1 |
| 16 | 2018-08-08 | 1 |
+------+------------+------------+
select * from soldproduct;
+--------+-------------+----------+-------+------------+
| billid | productname | quantity | price | totalprice |
+--------+-------------+----------+-------+------------+
| 11 | book | 2 | 100 | 200 |
| 11 | pen | 10 | 10 | 100 |
| 11 | pencil | 5 | 2 | 10 |
| 12 | pencil | 5 | 2 | 10 |
| 13 | pen | 10 | 10 | 100 |
| 13 | book | 2 | 100 | 200 |
| 14 | pen | 1 | 10 | 10 |
| 14 | bottle | 1 | 75 | 75 |
| 15 | phone | 1 | 5000 | 5000 |
| 16 | lock | 15 | 50 | 750 |
+--------+-------------+----------+-------+------------+
I need to find the highest bill id using totalprice.
I tried using
select billid,sum(totalprice)
from soldproduct
where billid in (select id from bill where solddate >= date_sub(curdate(),interval 1 month))
group by billid
order by totalprice desc;
and my output is
+--------+-----------------+
| billid | sum(totalprice) |
+--------+-----------------+
| 15 | 5000 |
| 16 | 750 |
| 11 | 310 |
| 13 | 300 |
| 12 | 10 |
| 14 | 85 |
+--------+-----------------+
How do i get the same output with a single query using joins (without using subquery)?
try the following join
select billid,sum(totalprice)
from soldproduct
join bill on soldproduct.billid = bill.id and solddate >= date_sub(curdate(),interval 1
month)
group by billid
order by totalprice desc;
Can you try the below query:(I do not tested it out)
SELECT billid, SUM(totalprice)
FROM soldproduct SP
JOIN bill B ON (B.id = SP.billid)
WHERE B.solddate BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE()
GROUP BY SP.billid
ORDER BY SP.totalprice DESC;

MYSQL Complex Join one-to-many

I have the following tables:
clients:
| id | name | code | zone |
--------------------------------
| 1 | client 1 | a1b1 | zone1|
| 2 | client 2 | a2b2 | zone2|
contacts:
| id_contact | first_name | last_name |
----------------------------------------
| 11 | first1 | last1 |
| 22 | first2 | last2 |
| 33 | first3 | last3 |
| 44 | first4 | last4 |
client_contacts:
| id_client | id_contact |
--------------------------
| 1 | 11 |
| 1 | 22 |
| 1 | 33 |
| 2 | 11 |
| 2 | 44 |
offers:
| id_offer | id_client | value |
--------------------------
| 111 | 1 | 100 |
| 222 | 1 | 200 |
| 333 | 1 | 300 |
| 444 | 2 | 400 |
I would like through a optimal select to obtain:
| id_client | name | code | zone | contacts_pers | total_offer_value |
----------------------------------------------------------------------------
| 1 | client 1 | a1b1 | zone1 | first1 last1; | 600 |
first2 last2;
first3 last3;
| 2 | client 2 | a2b2 | zone2 | first1 last1; | 400 |
first4 last4;
I know how to get the desired result with "group_concat" and stored procedures for "total_offer_value". But how to get the desired result from a single efficient select?
SELECT c.id, c.name, c.code, c.zone, GROUP_CONCAT(DISTINCT CONCAT(co.first_name, " ", c.last_name) SEPARATOR ";") AS contact_pers, func_total_offer_value(c.id) AS total_offer_value
FROM clients c
LEFT OUTER JOIN (client_contacts cc, contacts co) ON ( c.id = cc.id_client AND cc.id_contact = co.id_contact )
GROUP BY c.id

select sum of product price for every 1 id productcategory

i want to find solution for my query problem. I need to find the SUM of all priceProduct*quantity and separated with each of productcategory. I have already made a query, but it takes longer time to executed it. this is my query,
SELECT
pb.ProductCategoryID,
pb.ProductCategoryDescription,
(SELECT
SUM((SELECT pd.HPP FROM `price details` pd WHERE pd.ProductID = pdt.ProductID ORDER BY pd.PriceDetailID DESC LIMIT 1)*
(SELECT StockProductBallance FROM `stock product` sp WHERE sp.ProductID = pdt.ProductID ORDER BY sp.StockProductID DESC LIMIT 1))
FROM product pdt
WHERE pdt.ProductCategoryID = pb.ProductCategoryID
) AS Total
FROM `product category` pb
GROUP BY pb.ProductCategoryID
this my example table
table product:
+------+-------+
| id_p | id_pc |
+------+-------+
| 1 | 3 |
| 2 | 4 |
| 3 | 3 |
| 4 | 4 |
+------+-------+
table productcategory:
+-------+---------+
| id_pc | pc_name |
+-------+---------+
| 3 | new_pc |
| 4 | old_pc |
+-------+---------+
table price details:
+---------------+------+-----+
| PriceDetailID | id_p | hpp |
+---------------+------+-----+
| 1 | 1 | 100 |
| 2 | 1 | 110 |
| 3 | 1 | 120 |
| 4 | 2 | 200 |
| 5 | 2 | 210 |
| 6 | 2 | 220 |
+---------------+------+-----+
table stockProduct:
+-----------------+------+---------------+
| id_stockProduct | id_p | stockballance |
+-----------------+------+---------------+
| 1 | 1 | 10 |
| 2 | 1 | 11 |
| 3 | 1 | 12 |
| 4 | 2 | 20 |
| 5 | 2 | 21 |
| 6 | 2 | 22 |
+-----------------+------+---------------+
Really need your help guys, for better query..