Get several data from SQL query based on different conditions - mysql

I have the following code:
SELECT DISTINCT m.solde_total_client
,c.client_nom
,co.contenant_nom
FROM `mouvement` m, `client` c, `contenant` co
WHERE c.client_id = m.client_id
AND co.contenant_id = m.contenant_id
ORDER BY m.movement_date DESC
LIMIT 1;
And I get as a result one total sold of one client. But I want to get one for each contenant for each client. (But it still need to be the last one by date)
I'm getting as a result:
And I want to get several result like that such as:
Leclerc | Geobox | 50
SuperU | Box | 40
...
sold_total_client is what the client as after a shipment, there is several shipment and the sold is updated at every move, so the last one by date is the actual sold. So I have to get the last move of every contenant of every client.

You could try using a subquery for max_date group by client_id, contenant_id
SELECT
m.solde_total_client,
m.`mouvement_date`,
c.client_nom,
co.contenant_nom
FROM
`mouvement` m
INNER JOIN
(SELECT
MAX(mouvement_date) max_date, client_id, contenant_id
FROM
`mouvement`
GROUP BY
client_id, contenant_id) t ON t.client_id = m.client_id
AND m.contenant_id = t.contenant_id
AND t.max_date = m.`mouvement_date`
INNER JOIN
`client` c ON c.client_id = m.client_id
INNER JOIN
`contenant` co ON co.contenant_id = m.contenant_id
ORDER BY
m.`mouvement_date`

Related

Select from SQL database information with newest revisions

I coding web app for my client and have issue with selecting from database raports with newest revisions.
SELECT
raports.*,
r1.*,
users.*,
(SELECT COUNT(*) FROM changes WHERE changes.changes_raports_id = raports.raports_id) as changes,
(SELECT changes.changes_date FROM changes WHERE changes.changes_raports_id = raports.raports_id ORDER BY changes.changes_date DESC LIMIT 1) as last_change,
(SUM(injuries.injuries_min_procent) / COUNT(injuries_to_raports.injuries_to_raports_id)) as min,
(SUM(injuries.injuries_max_procent) / COUNT(injuries_to_raports.injuries_to_raports_id)) as max
FROM raports
LEFT JOIN users
ON users.users_id = raports.raports_users_id
LEFT JOIN changes
ON changes.changes_raports_id = raports.raports_id
LEFT JOIN raports_to_changes r1
ON r1.raports_to_changes_raports_id = raports.raports_id
LEFT JOIN injuries_to_raports
ON injuries_to_raports.injuries_to_raports_raports_id = r1.raports_to_changes_raports_id
LEFT JOIN injuries
ON injuries_to_raports.injuries_to_raports_injuries_id = injuries.injuries_id
WHERE r1.raports_to_changes_changes_id = (SELECT max(raports_to_changes_changes_id) FROM raports_to_changes r2 WHERE r2.raports_to_changes_raports_id = r1.raports_to_changes_raports_id)
GROUP BY raports.raports_id ORDER BY raports.raports_id ASC;
In columns max and min i have not correct average from injuries. When i checked it and count all injuries i had 36 when true number is 2 but i have 18 revisions. So is logic that i have looped COUNT with all revisions but i want only the newest
I try changing WHERE statements and more LEFT JOINs but nothing helped.
Could someone fixed that code?
Thank you in advanced
Based on the clues revealed by your queries, the data model may look like this:
The select list shows that you need:
users information of a reports_id
aggregated injuries_min_procent and injuries_max_procent at raports_id level. (see cte_raport_injuries)
number of changes of a raports_id (see cte_raport_changes)
the last change_date of a raports_id (see cte_raport_changes)
I'm not sure about the need for raports_of_changes based on information revealed in the question, so I'm going to ignore it for now.
with cte_raport_injuries as (
select r.raports_id,
sum(i.injuries_min_procent) / count(*) as injuries_min_procent,
sum(i.injuries_max_procent) / count(*) as injuries_max_procent
from raports r
join injuries_to_raports ir
on r.raports_id = ir.injuries_to_raports_raports_id
join injuries i
on ir.injuries_to_raports_injuries_id = i.injuries_id
group by r.raports_id),
cte_raport_changes as (
select r.raports_id,
count(c.changes_id) as changes,
max(c.changes_date) as last_change
from raports r
join changes c
on r.raports_id = c.changes_raports_id
group by r.raports_id)
select u.users_id,
r.raports_id,
ri.injuries_min_procent,
ri.injuries_max_procent,
rc.changes,
rc.last_change
from raports r
join users u
on r.raports_users_id = u.users_id
join cte_raport_injuries ri
on r.raports_id = ri.raports_id
join cte_raport_changes rc
on r.raports_id = rc.raports_id;
The result looks like this:
users_id|raports_id|injuries_min_procent|injuries_max_procent|changes|last_change|
--------+----------+--------------------+--------------------+-------+-----------+
1| 11| 15.0000| 25.0000| 2| 2022-12-02|
So my question for you is what's in reports_to_changes that you need and what's its relationship between others? For further involvement from the community, you may want to share the following information in text format:
DDLs of each tables (primary key, foreign key, column names & data types)
Some representable sample data and basic business rules
Expected output

Count(*) as inside a JOIN on SQL Query

I have the following query for a report all is working fine, but I need to add a variable in the report that totals up the number of records for each record returned based off the number of records in the "manheim_auction_listings" record. I feel like it needs to be inside a join but everywhere I would the "COUNT(*) AS num_of_runs" it seems to make the whole query only return a single line with the count the total number of records in the query rather than all the lines with a variable num_of_runs with the number of "manheim_auction_listings" records for each CAR record.
SELECT products.client_id,
clients.name AS client_name,
manheim_auction_lanes.lane_number,
manheim_auction_listings.sequence,
manheim_auction_listings.gross_sale_price,
products.asking_price, products.asking_price_condition,
manheim_auctions.auction_date,
manheim_auctions.auction_number,
product_purchases.total_spent,
product_purchases.purchase_price
FROM manheim_auction_listings
JOIN cars ON
cars.id = manheim_auction_listings.car_id
JOIN products ON
cars.product_id = products.id
JOIN product_purchases ON
current_product_purchase_id = product_purchases.id
JOIN manheim_auctions ON
manheim_auctions.id = manheim_auction_listings.manheim_auction_id
JOIN manheim_auction_lanes ON
manheim_auction_lanes.id = manheim_auction_listings.manheim_auction_lane_id
JOIN clients ON
clients.id = products.client_id
AND clients.id LIKE $P{LoggedInUserAttribute_ClientID}
WHERE
manheim_auctions.auction_number = $P{SaleNumber}
AND manheim_auctions.`year` = $P{SaleYear}
ORDER BY manheim_auction_lanes.lane_number DESC,
manheim_auction_listings.sequence DESC
Please try the following...
SELECT products.client_id,
clients.name AS client_name,
manheim_auction_lanes.lane_number,
manheim_auction_listings.sequence,
manheim_auction_listings.gross_sale_price,
num_of_runs,
products.asking_price, products.asking_price_condition,
manheim_auctions.auction_date,
manheim_auctions.auction_number,
product_purchases.total_spent,
product_purchases.purchase_price
FROM ( SELECT manheim_auction_id AS manheim_auction_id,
COUNT( manheim_auction_id ) AS num_of_runs
FROM manheim_auction_listings
GROUP BY manheim_auction_id
) AS num_of_runs_finder
JOIN manheim_auction_listings ON manheim_auction_listings.manheim_auction_id = num_of_runs.manheim_auction_id
JOIN cars ON cars.id = manheim_auction_listings.car_id
JOIN products ON cars.product_id = products.id
JOIN product_purchases ON current_product_purchase_id = product_purchases.id
JOIN manheim_auctions ON manheim_auctions.id = manheim_auction_listings.manheim_auction_id
JOIN manheim_auction_lanes ON manheim_auction_lanes.id = manheim_auction_listings.manheim_auction_lane_id
JOIN clients ON clients.id = products.client_id
AND clients.id LIKE $P{LoggedInUserAttribute_ClientID}
WHERE manheim_auctions.auction_number = $P{SaleNumber}
AND manheim_auctions.`year` = $P{SaleYear}
ORDER BY manheim_auction_lanes.lane_number DESC,
manheim_auction_listings.sequence DESC
This works by joining your other tables to one that calculates the number of listings associated with each manheim_auction_id, effectively appending a manheim_auction_id's count to each row where that manheim_auction_id occurs.
If num_of_runs is calculated on some other criteria, then please advsie me accordingly.
If you have any questions or comments, then please feel free to post a Comment accordingly.

MySql Fetch rows that have latest date

Here's the code:
SELECT tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, MAX(tblitemprice.dtmItemPasOf) AS Expr1,
tblitemprice.dblItemPAmount
FROM tblclassification INNER JOIN
tblitem ON tblclassification.strClasCode = tblitem.strItemClasCode INNER JOIN
tblitemprice ON tblitem.strItemCode = tblitemprice.strItemPItemCode INNER JOIN
tblitemunit ON tblitemprice.strItemPItemUnitCode = tblitemunit.strItemUnitCode INNER JOIN
tblvendor ON tblclassification.strClasCode = tblvendor.strVendClasCode AND tblitemprice.strItemPVendCode = tblvendor.strVendCode AND tblitem.deleted_at IS NULL
GROUP BY tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, tblitemprice.dblItemPAmount
And Here's the Result:
CODE NAME UNIT VENDOR DATE PRICE
ITEM101-Fudgee Bar-Piece-Imus Palengke 10/9/20165:03:32AM - 6.5
ITEM102-Yum Burger-Box-Jollibee Lumina Mall-10/9/2016 6:13:27 AM - 2500
ITEM102-Yum Burger-Piece-Jollibee Lumina Mall-10/9/2016 4:42:28 AM - 30
ITEM102-Yum Burger-Piece-Jollibee Lumina Mall-10/13/2016 12:37:31 PM- 35
ITEM102-Yum Burger Piece Jollibee Lumina Mall 10/14/2016 10:05:44 PM 40
What I want to happen is to fetch only the row with the latest price. Can someone help me please.
I want to fetch the Item101 and only the last row to ITEM102 since it is the latest.
If I understand correctly, you're looking for the last updated row price. It's easy to do so:
Order your data by their relevant timestamp in reversed order (ORDER BY <FIELD_NAME> DESC). From what I gather from your query and results, Expr1 is the latest date for a given price.
Only pick a single element (LIMIT 1). Since your data is already ordered in reverse chronological order, you're sure to pick the latest one.
The SQL for that would be
SELECT tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, MAX(tblitemprice.dtmItemPasOf) AS Expr1,
tblitemprice.dblItemPAmount
FROM tblclassification INNER JOIN
tblitem ON tblclassification.strClasCode = tblitem.strItemClasCode INNER JOIN
tblitemprice ON tblitem.strItemCode = tblitemprice.strItemPItemCode INNER JOIN
tblitemunit ON tblitemprice.strItemPItemUnitCode = tblitemunit.strItemUnitCode INNER JOIN
tblvendor ON tblclassification.strClasCode = tblvendor.strVendClasCode AND tblitemprice.strItemPVendCode = tblvendor.strVendCode AND tblitem.deleted_at IS NULL
GROUP BY tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, tblitemprice.dblItemPAmount
ORDER BY Expr1 DESC
LIMIT 1
Try it out !

counting methodolegy in SQL Server query

Good day everyone…
I have a database that has the following:
Division table that linked to Employee table.
Group table, i.e. courses categories, that linked to Courses table.
and these table linked together thru Curses_Employee table .
so far I managed to come up with a query that give me the number of users who toke certain course in each group/category like the following output table:
groupName | DivisionName| courseName|Total Number of Participants
and here is my query for the above scheme:
SELECT dbo.groups.GroupName, dbo.Divisions.DivisionName, dbo.courses.CourseName, COUNT(dbo.employee_courses.courseId) AS [Total Number of Participants]
FROM dbo.employee AS employee_1 INNER JOIN
dbo.Divisions ON employee_1.DivisionCode = dbo.Divisions.SapCode INNER JOIN
dbo.employee_courses ON employee_1.Username = dbo.employee_courses.employeeId INNER JOIN
dbo.courses ON dbo.employee_courses.courseId = dbo.courses.CourseID INNER JOIN
dbo.groups ON dbo.courses.GroupID = dbo.groups.ID
WHERE (dbo.courses.GroupID = 2)
GROUP BY dbo.courses.CourseID, dbo.courses.CourseName, dbo.Divisions.DivisionName, dbo.groups.GroupName
now I want to add two columns the total number of employee in each division as well as the % like the following table:
groupName | DivisionName| courseName|Total Number of Participants |Total Number of Employee |%
I tried this query but it give me an error:
SELECT dbo.groups.GroupName, dbo.Divisions.DivisionName, dbo.courses.CourseName, COUNT(dbo.employee_courses.courseId) AS [Total Number of Participants],
(SELECT COUNT(Name) AS Expr1
FROM dbo.employee
WHERE (DivisionCode = employee_1.DivisionCode)
GROUP BY DivisionCode) AS [Total Number of Employee]
FROM dbo.employee AS employee_1 INNER JOIN
dbo.Divisions ON employee_1.DivisionCode = dbo.Divisions.SapCode INNER JOIN
dbo.employee_courses ON employee_1.Username = dbo.employee_courses.employeeId INNER JOIN
dbo.courses ON dbo.employee_courses.courseId = dbo.courses.CourseID INNER JOIN
dbo.groups ON dbo.courses.GroupID = dbo.groups.ID
WHERE (dbo.courses.GroupID = 2)
GROUP BY dbo.courses.CourseID, dbo.courses.CourseName, dbo.Divisions.DivisionName, dbo.groups.GroupName
the error message:
column 'dbo.employee.DivisionCode' is invalid in the select list
because it is not contained in either as aggregate function or the
GROUP BY clause.

avg in query - mysql

I have this query
SELECT salary
FROM worker W
JOIN single_user U ON u.users_id_user = W.single_user_users_id_user
JOIN university_has_single_user US ON US.single_user_users_id_user = U.users_id_user
JOIN course C ON C.id_course = US.course_id_course
JOIN formation_area FA ON FA.id_formation_area = C.formation_area_id_formation_area
WHERE FA.area = "Multimédia"
GROUP BY users_id_user
...that gave this output:
salary
--------
1400.00
800.00
How can I calculate the avg of this output? If I add:
SELECT round(avg (salary), 0)
...the output is again 1400.00 and 800.00, not the avg (because the group by).
Use:
SELECT AVG(DISTINCT salary)
FROM worker W
JOIN single_user U ON u.users_id_user = W.single_user_users_id_user
JOIN university_has_single_user US ON US.single_user_users_id_user = U.users_id_user
JOIN course C ON C.id_course = US.course_id_course
JOIN formation_area FA ON FA.id_formation_area = C.formation_area_id_formation_area
WHERE FA.area = "Multimédia"
Because the salary column is not wrapped in an aggregate, per the documentation, the values you see are arbitrary (can't be guaranteed 100% of the time).
Usually, you'd need a derived table to get the average of the distinct values but MySQL's AVG supports using DISTINCT within it.