Get the last booking by its status (mysql) - mysql

I currently have a table that contains reservations. Another table with different status assigned to a reservation. A reservation with several status to keep track of the different status.
I would like to retrieve all the bookings in relation to the LAST status of the reservation.
| | | | |
|-------------|------------|----------------|-----------------------|
| Booking | | | |
| id | name | | |
| 1 | aaa | | |
| 2 | bbb | | |
| 3 | ccc | | |
| | | | |
| Status | | | |
| id | booking_id | type_status_id | date_of_change_status |
| 1 | 1 | 1 | xxx-xx-xx 00:00:00 |
| 2 | 1 | 2 | xxx-xx-xx 00:00:00 |
| 3 | 2 | 1 | xxx-xx-xx 00:00:00 |
| 4 | 2 | 2 | xxx-xx-xx 00:00:00 |
| | | | |
| Type_status | | | |
| id | name | | |
| 1 | Started | | |
| 2 | Updated | | |
| 3 | Finished | | |
Here is the code that I have for the moment, it returns well to me the reservations which passed by the status but not like last status.
SELECT b.name, b.id, b.date_booking, b.price, b.reference FROM booking b
INNER JOIN (SELECT MAX(s.id), s.booking_id, s.type_status_id FROM status s
WHERE s.type_status_id = 5
GROUP BY booking_id) AS status_max
ON b.id = status_max.booking_id
Thanks

Calculate the "latest" date of status change in a subquery using MAX() then include that as a subquery in the joins to restrict which rows from the status table get returned.
select
*
from Booking b
inner join Status s on b.id = s.bookingid
inner join (
select booking_id, max(date_of_change_status) latest_status_date
from status
group by
) l on b.id = l.bookingid
and s.date_of_change_status = l.latest_status_date
inner join Type_status ts on s.type_status_id = ts.id

Related

MySQL Join one table to other two tables

I have a MySQL database including following tables that used to maintain transactions of some documents.
tbl_documents Table
+----+---------+------+---------+
| id | file_no | name | subject |
+----+---------+------+---------+
| 1 | A/10 | F1 | a |
| 2 | A/11 | F2 | b |
| 3 | A/12 | F3 | c |
| 4 | A/13 | F4 | d |
+----+---------+------+---------+
tbl_requests
+----+-------------+----------------+---------------+
| id | document_id | requested_date | approved_date |
+----+-------------+----------------+---------------+
| 1 | 1 | 2019-12-01 | 2019-12-02 |
| 2 | 2 | 2019-12-08 | 2019-12-08 |
+----+-------------+----------------+---------------+
tbl_issues
+----+-------------+------------+
| id | document_id | issue_date |
+----+-------------+------------+
| 1 | 1 | 2019-12-05 |
| 2 | 2 | 2019-12-10 |
+----+-------------+------------+
I want to get the following / Desired output by joining above three tables.
Desired Output
+---------+------+---------+----------------+---------------+------------+
| file_no | name | subject | requested_date | approved_date | issue_date |
+---------+------+---------+----------------+---------------+------------+
| A/10 | F1 | a | 2019-12-01 | 2019-12-02 | 2019-12-05 |
| A/11 | F2 | b | 2019-12-08 | 2019-12-08 | 2019-12-10 |
+---------+------+---------+----------------+---------------+------------+
To do that, I used the following query
select tbl_documents.file_no, tbl_documents.name, tbl_documents.subject, requested_date, approved_date, tbl_issues.issue_date
from tbl_documents
right join tbl_requests on tbl_requests.document_id=tbl_documents.id
right join tbl_issues on tbl_issues.document_id=tbl_documents.id
But didn't get the expected output. Can anyone help ?
Just use inner joins, as in:
select
d.file_no,
d.name,
d.subject,
r.requested_date,
r.approved_date,
i.issue_date
from tbl_documents d
join tbl_requests r on r.document_id = d.id
join tbl_issues i on i.document_id = d.id

Verification of dates mySQL

I need to check that the steps of each project were done between the start and end dates of the project. (Write a query that allows a human to know if this is the case)
This is my code:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin
FROM (SELECT idprojet,
datedebut,
datefin
FROM projet) AS p
LEFT JOIN etapexprojet AS e
ON e.datedebut < p.datedebut
AND e.datefin < p.datefin
ORDER BY idprojet;
The table of EtapexProjet (There is other date inside the table EtapexProjet ):
+---------+----------+-------------+--------------+--+
| idEtape | idProjet | dateDebut | dateFin | |
+---------+----------+-------------+--------------+--+
| 1 | 1 | 2011-07-01 | 2011-09-01 | |
| 1 | 2 | 2012-05-01 | 2012-05-10 | |
| 1 | 3 | 2011-11-01 | 2012-01-20 | |
| 2 | 1 | | | |
| 2 | 2 | | | |
| 2 | 3 | | | |
| 3 | 1 | | | |
| 3 | 2 | | | |
| 3 | 3 | | | |
| 4 | 1 | | | |
| 4 | 2 | | | |
| 5 | 2 | | | |
+---------+----------+-------------+--------------+--+
The table of Projet:
+----------+----------+-----------+------------+------------+---------------+--+
| idProjet | idClient | nomProjet | dateDebut | dateFin | idResponsable | |
+----------+----------+-----------+------------+------------+---------------+--+
| 1 | 321 | Devl. | 2011-08-01 | | 1876 | |
| 2 | 321 | Maint. | 2012-05-01 | 2012-07-23 | 2231 | |
| 3 | 345 | Devl.2 | 2011-11-01 | | 2231 | |
+----------+----------+-----------+------------+------------+---------------+--+
My expected results is that to check/verify if the beginning and ending date of each idEtape is between the beginning date and the ending date of the projet its related.
You don't need to use a Derived Table (sub-select query), as you are not doing any sort of aggregation, etc on the projet table.
I believe that you are only concerned with the idetape values which lie inside the projet's datedebut and datefin.
You can change Left Join to Inner Join due to above mentioned point.
I have also increased the horizon of cases to check, as there is a possibility of datefin being NULL in either of the tables.
Try the following instead:
SELECT e.idetape,
e.idprojet,
e.datedebut,
e.datefin,
p.datedebut AS projet_datedebut,
p.datefin AS projet_datefin
FROM EtapexProjet AS e
JOIN Projet AS p
ON p.idprojet = e.idprojet
AND e.datedebut >= p.datedebut
AND (e.datefin <= p.datefin OR
p.datefin IS NULL OR
e.datefin IS NULL
)
ORDER BY e.idprojet,
e.idetape;
Please try the code below:
SELECT nomEtape, livrable, idEtape, idProjet
FROM Etape
WHERE idEtape= (SELECT MAX(idEtape)
FROM EtapexProjet
WHERE DISTINCT(idProjet)
);

Using inner join and not in together in mysql

I have a wordpress database with default users table and two custom tables as below
1. wp_users
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 2 | Nina |
| 3 | rakib |
2. wp_invite
| post_id | user_id | status |
|---------|---------|----------|
| 3342 | 1 | accepted |
| 3342 | 2 | accepted |
| 3342 | 3 | accepted |
3. wp_rating
| id | reviwer | reviewed | post | know | skill | time | comm |
|----|---------|----------|------|------|-------|------|------|
| 2 | 3 | 1 | 3342 | b | b | b | b |
| 5 | 1 | 2 | 2122 | a | c | d | a |
| 7 | 2 | 3 | 3342 | d | a | b | c |
i want to select * from wp_invite where status = accepted, display_name from wp_users and then want to exclude rows from the result where all of these three conditions meet
1. wp_invite.user_id is not equal to wp_rating.reviewer and
2. wp_invite.user_id is not equal to wp_rating.reviewed and
3. wp_invite.post_id is not equal to wp_rating.post.
My desired output for post = 3342 and reviewer = 3
| user_id | display_name |
|---------|--------------|
| 2 | Nina |
| 3 | rakib |
My desired output for post = 3342 and reviewer = 2
| user_id | display_name |
|---------|--------------|
| 1 | Ibbs |
| 2 | Nina |
My desired output for post = 2122 and reviewer = 2
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 2 | Nina |
| 3 | rakib |
My desired output for post = 2122 and reviewer = 1
| id | display_name |
|----|--------------|
| 1 | Ibbs |
| 3 | rakib |
I have tried the following query but my output is empty:
SELECT wp_invite.user_id, wp_users.display_name, wp_invite.post_id
FROM wp_invite
INNER JOIN wp_users ON wp_invite.user_id = wp_users.id
WHERE (status = 'accepted')
AND user_id NOT IN (SELECT reviewer FROM wp_rating)
AND user_id NOT IN (SELECT reviewed FROM wp_rating)
AND post_id NOT IN (SELECT post FROM wp_rating)
ID should be capitalized:
inner join wp_users on wp_invite.user_id = wp_users.ID

How to get count of combinations from database?

How to get count of combinations from database?
I have to database tables and want to get the count of combinations. Does anybody know how to put this in a database query, therefore I haven't a db request for each trip?
Trips
| ID | Driver | Date |
|----|--------|------------|
| 1 | A | 2015-12-15 |
| 2 | A | 2015-12-16 |
| 3 | B | 2015-12-17 |
| 4 | A | 2015-12-18 |
| 5 | A | 2015-12-19 |
Passengers
| ID | PassengerID | TripID |
|----|-------------|--------|
| 1 | B | 1 |
| 2 | C | 1 |
| 3 | D | 1 |
| 4 | B | 2 |
| 5 | D | 2 |
| 6 | A | 3 |
| 7 | B | 4 |
| 8 | D | 4 |
| 9 | B | 5 |
| 10 | C | 5 |
Expected result
| Driver | B-C-D | B-D | A | B-C |
|--------|-------|-----|---|-----|
| A | 1 | 2 | - | 1 |
| B | - | - | 1 | - |
Alternative
| Driver | Passengers | Count |
|--------|------------|-------|
| A | B-C-D | 1 |
| A | B-D | 2 |
| A | B-C | 1 |
| B | A | 1 |
Has anybody an idea?
Thanks a lot!
Try this:
SELECT Driver, Passengers, COUNT(*) AS `Count`
FROM (
SELECT t.ID, t.Driver,
GROUP_CONCAT(p.PassengerID
ORDER BY p.PassengerID
SEPARATOR '-') AS Passengers
FROM Trips AS t
INNER JOIN Passengers AS p ON t.ID = p.TripID
GROUP BY t.ID, t.Driver) AS t
GROUP BY Driver, Passengers
The above query will produce the alternative result set. The other result set can only be achieved using dynamic sql.
Demo here

Join table to itself to find products bought one after the other

I have a table which contains the following columns:
+------------------+----------+
| date_of_purchase | product |
+------------------+----------+
| 2013-06-18 | A |
| 2013-07-18 | A |
| 2013-08-24 | A |
| 2013-10-21 | A |
| 2013-11-20 | A |
| 2013-12-20 | A |
| 2014-01-20 | A |
| 2014-03-24 | A |
| 2014-03-24 | B |
| 2014-04-23 | B |
| 2014-04-23 | A |
| 2014-05-16 | B |
| 2014-05-23 | A |
+------------------+----------+
And I want to get something like this:
+----------+----------+------------+------------+
| product1 | product2 | date_a | date_b |
+----------+----------+------------+------------+
| A | B | 2014-01-20 | 2014-03-24 |
| A | B | 2014-03-24 | 2014-04-23 |
| B | A | 2014-05-16 | 2014-05-23 |
| A | B | 2014-04-23 | 2014-05-16 |
+----------+----------+------------+------------+
What I am trying to do is to check which product "B" is bought after product "A".
I am new to stack-overflow, so the way I am asking this question might seem vague. But need help on this one.
The derived table keeps track of the next purchase date using a variable which is then used to check whether a different product was purchased on the next purchase date
select t1.product, t2.product, t1.date_of_purchase, t2.date_of_purchase from (
select date_of_purchase, product,
#nextDateOfPurchase nextDateOfPurchase,
#nextDateOfPurchase := date_of_purchase
from Table1 t
order by date_of_purchase desc
) t1 join Table1 t2 on t2.date_of_purchase = t1.nextDateOfPurchase
and t2.product <> t1.product
and t2.date_of_purchase <> t1.date_of_purchase
order by t1.date_of_purchase
http://sqlfiddle.com/#!9/44b24/3