How to find correct value in mysql - mysql

I have a question about finding the correct value from my scenario.
I have two table like this:
shift table
shift_id | shift_user | gate
-------- | ---------- | ------
1 | 1001 | 1
1 | 1001 | 2
1 | 1001 | 3
2 | 1002 | 1
2 | 1002 | 2
2 | 1002 | 3
3 | 1003 | 1
3 | 1003 | 3
Transaction Table
id | shift_id | sale | gate
-----|------------|---------|----------
1 | 1 | 2000 | 1
2 | 1 | 30000 | 2
3 | 1 | 40000 | 3
4 | 2 | 300 | 1
5 | 2 | 4000 | 2
6 | 2 | 3200 | 3
7 | 3 | 5500 | 1
8 | 3 | 100000 | 3
How to calculate sum of the sales for each shift_id?
Please provide me a good way with query.
Thanks a lot.
:)
EDIT
From the comment section of an answer it became clear that we need to get the sum of sales of a specific shift.

Use query like:
Select s.shift_id, sum(sale) from shift s INNER JOIN transaction
ON s.shift_id=t.shift_id group by s.shift_id

That's a simple grouping query. Try this:
SELECT shift_id, SUM(sale)
FROM transactions
GROUP BY shift_id;
Here is a fiddle

You need simple grouping
select shift_id, sum(sale)
from transactions
group by shift_id
If you need to get this result for a specific group, then do it like this
select shift_id, sum(sale)
from transactions
group by shift_id
having shift_id = 1

I found a solution for my question.
I have used following query:
select sum(sale) from transaction inner join shift on shift.shift_id=transaction.shift_id and shift.gate=transaction.gate;
This returns the correct result.
Thank for your reply, dear friends.

Related

Joining two MySQL datasets by date as well as id

I am struggling to find a way to efficently join two datasets using a single query
Dataset one can be returned using the following query:
SELECT hours_person_id, hours_date, hours_job, SUM(hours_value) AS hours
FROM hours
WHERE hours_status = 1
GROUP BY hours_person_id, hours_date, hours_job
which gives a dataset similar to
| 1 | 2020-06-07 | 101 | 25 |
| 1 | 2020-06-07 | 102 | 10 |
| 1 | 2020-06-07 | 103 | 5 |
| 2 | 2020-06-07 | 101 | 30 |
| 2 | 2020-06-07 | 104 | 10 |
From which we can get total hours per week, per job, etc...
Our second dataset gives us the hourly rates for the each person. The problem is that this table contains both historical and future hourly rates, so the join needs to ensure that the rate applies to the correct person_id and date. There could also be more than 1 rate for a person on a date.
The following gives all the rates that are active
SELECT rate_person_id, rate_date, rate_value
FROM rates
WHERE rate_active = 1
Which could look like
| 1 | 2020-01-01 | 20.00 |
| 1 | 2020-05-01 | 25.00 |
| 1 | 2020-07-01 | 22.00 |
| 2 | 2020-01-01 | 22.00 |
| 2 | 2020-05-01 | 24.00 |
| 3 | 2020-05-01 | 20.00 |
| 3 | 2020-05-01 | 21.00 |
| 3 | 2020-07-01 | 18.00 |
So for the hours above the rate from the 2020-05-01 would be the expected result, with the 21.00 value being the result for person_id === 3
Can what I am looking for be done in a single Query, or am I better off Joining two subqueries?
Update
As requested here is a fiddle that represents the above
https://www.db-fiddle.com/f/oiUpTnajY6M6ZTfZgRf4kT/0
As you can see we have a query that returns the correct data, but this query does not scale to our curennt data set (1.8m lines and more sub tables)
So for the hours above the rate from the 2020-05-01 would be the expected result, with the 21.00 value being the result for person_id === 1
From your rates output, person_id = 1 was never on rate value 21.00 .
| 1 | 2020-01-01 | 20.00 |
| 1 | 2020-05-01 | 25.00 |
| 1 | 2020-07-01 | 22.00 |
For 2 active rates for a person, do you need the most recent rate or you need the rate in the month where he worked. If there is no rate for that month then do you want 0 rate or something else.
SELECT h.*,
(SELECT rate_value
FROM rates r
WHERE h.hours_person_id = r.rate_person_id AND
r.date <= h.date
ORDER BY r.date DESC
LIMIT 1
) as rate_value
FROM hours h
I don't see what active has to do with the question, because you need to go back in time. You can then aggregate or do whatever you want once you have the correct rate on the date.

How to join 1 table to another table and get count result per date

I have 3 tables with corresponding fields.
Table 1 (List of Machines)
Machine_No | Machine_Description
1 | Hitachi
2 | Jet Printer
3 | Sumi
Table 2 (List of Manpower)
ID_Number | Employee_Name | Machine_No
1 | Taylor | 3
2 | James | 2
3 | David | 1
Table 3 (Actual Manpower use per machine)
Machine_No | Employee_Number | Date Posted
1 | 1 | 15-10-2019
1 | 2 | 15-10-2019
1 | 3 | 15-10-2019
Now... I want the results to go like this.
Machine_Now | Count(Employee Number) | Date_Posted
1 | 3 | 15-10-2019
Try this, it may work, if I understand your question correctly.
select Machine_No,Date_Posted,count(*) from Table3 group by Machine_No,Date_Posted;

average, count, group by in select query

I am developing a booking engine web app.
Once an user made a booking it goes to this table.
id | Promo_code | total | arrival_date | departure_date | booked_date
1 | ABC1 | 1000 | 2019-02-06 | 2019-02-10 | 2019-02-02
2 | ABC1 | 2500 | 2019-02-07 | 2019-02-11 | 2019-02-03
3 | ABC1 | 3000 | 2019-02-12 | 2019-02-15 | 2019-02-03
4 | ABC2 | 5000 | 2019-02-07 | 2019-02-11 | 2019-02-02
5 | null | 3000 | 2019-02-12 | 2019-02-15 | 2019-02-01
Here the promo_code is what it names implies. If the user doesn't book with a promo_code it is null (5th record).
Hope other fields total, arrival_date, departure_date and booked_date are clear to you.
My question is I want to generate a report something like this.
promo_code | number_of_bookings | revenue | Average_length_of_stay | Average_depart_date | Average_reservation_revenue
ABC1 | 3 | 6500 | 3 | 5 | 2166
ABC2 | 1 | 5000 | 4 | 5 | 5000
This report is called revenue by promo code report.
If I explain what happend in this report is
Average_length_of_stay = (departure_date - arrival_date) / number_of_bookings
Average_depart_date = (departure_date - booked_date) / number_of_bookings
Of cause I could generate this report by the backend logic somehow. But I would be very painful. There must be a way to query this
in the SQL directly.
What I have done upto now is
SELECT promo_code ,count(*) as number_of_bookings,
sum(total) as revenue
FROM booking_widget.User_packages group by promo_code;
I am stuck with Average_length_of_stay, Average_depart_date and Average_reservation_revenue.
How do I get the average values which the group by clause?
It is trivial:
SELECT promo_code
, COUNT(*) AS number_of_bookings
, SUM(total) AS revenue
, AVG(DATEDIFF(departure_date, arrival_date)) AS average_length_of_stay
, AVG(DATEDIFF(departure_date, booked_date)) AS average_depart_date
, AVG(total) AS average_reservation_revenue
FROM t
GROUP BY promo_code

Need help/explanation to JOINED query

I'm kinda lost on what kind of SQL query I should do to achieve what I want.
Let's say I have three tables :
select * FROM trip;
| trip_id | title | description
----------------------------------
| 1 | title1 | desc1 |
| 2 | title2 | desc2 |
| 3 | title3 | desc3 |
| 4 | title4 | desc4 |
| 5 | title5 | desc5 |
| 6 | title6 | desc6 |
select * FROM weekly_report;
| report_id | trip_id| incident_id
----------------------------------
| 1 | 1 | (null) |
| 2 | 1 | (null) |
| 3 | 1 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 3 |
| 6 | 3 | (null) |
select * FROM incident;
| incident_id | error_code |
----------------------------------
| 1 | 22223 |
| 2 | 25456 |
| 3 | 25456 |
So for a little operationnal knowledge :
The trip table contains 1 record PER trip done by the customer.
The weekly_report contains A report per Week of the trip. (1 trip of 2 weeks will have 2 records, 1 trip or 5 weeks will have 5.. ).
The incident table contains 1 record per incident. (If an incident happened during a week : we create a record in the incident table, else we do nothing)
I'd like to find in a single query (or if it has to be, with subqueries) the number of trips where during at least a week there has been an incident declared for the error_code "25456".
Expected result from the sample data : 2 ( because for trip 2 and three there exist an incident with the error code 25456 ).
I can explain more if needed, is there anybody out there willing to help me ?
Thanks,
You need to take count of distinct trips for related incidents
select count(distinct w.trip_id)
from weekly_report w
inner join incident i
on w.incident_id = i.incident_id
where i.error_code = 25456;
Try this:
SELECT w.trip_id
FROM incident i
INNER JOIN weekly_report w ON i.incident_id=w.incident_id
WHERE error_code='25456'
and if you want the count,then
SELECT COUNT(w.trip_id)
FROM incident i
INNER JOIN weekly_report w ON i.incident_id=w.incident_id
WHERE error_code='25456'

MySQL Subselect Issue with two tables and aggregate functions into single query

I have 2 tables
Transaction table
+----+----------+-----+---------+----
| TID | CampaignID | DATE |
+----+----------+-----+---------+---+
| 1 | 5 | 2016-01-01 |
| 2 | 5 | 2016-01-01 |
| 3 | 2 | 2016-01-01 |
| 4 | 5 | 2016-01-01 |
| 5 | 1 | 2016-01-01 |
| 6 | 1 | 2016-02-02 |
| 7 | 3 | 2016-02-02 |
| 8 | 3 | 2016-02-02 |
| 9 | 5 | 2016-02-02 |
| 10| 4 | 2016-02-02 |
+----+----------+-----+---------+---+
Campaign Table
+-------------+----------------+--------------------
| CampaignID | DailyMaxImpressions | CampaignActive
+-------------+----------------+--------------------
| 1 | 5 | Y |
| 2 | 5 | Y |
| 3 | 5 | Y |
| 4 | 5 | Y |
| 5 | 1 | Y |
+-------------+----------------+--------------------
What I am trying to do is get a single random campaign where the the count in transaction table is less than the daily max impressions in the campaign table. I might also be passing a date s part of the query for the transaction table
So for CampaignId 1 there must be 4 trans of less in the transaction table and the Campaignactive must be a "Y"
Any help would be appreciated if this can be done in a single statement. ( mysql )
Thanks in advance,
Jeff Godstein
This should get it for you. The basic query is select each campaign that is active. The INNER query will pre-aggregate per campaign for the given date in question. From that, a LEFT-JOIN allows any campaign to be returned even if it does NOT exist within the subquery OR it DOES exist, but the count is less than that allowed for the date in question. The order by RAND() is obvious.
SELECT
c.CampaignID
from
Campaign c
LEFT JOIN
( select
t1.CampaignID,
count(*) as CampCount
from
Transaction t1
where
t1.Date = YourDateParameterValue
group by
t1.CampaignID ) as T
ON c.CampaignID = T.CampaignID
where
c.CampaignActive = 'Y'
AND ( t.CampaignID IS NULL
OR t.CampCount < c.DailyMaxImpressions )
order by
RAND()