enter image description hereI have an employee table. In that table I have n number of loan.. Now I want to select all the employees with his last taken loan value and date.. can anyone help me out in this.
There's what I've done so far:
SELECT employee_id,employee_name,department_name,
designation_name,PF_type,PF_number,Opening_balance,
MAX(Loan_id),MAX(loan_date), MAX(loan_amount)
FROM single_roww1
GROUP BY employee_id
I tried group by, limit and order by for this but of no use... I also tried to take the last occurence of the employee_id that also didn't work..
Update: to get the full row of max id:
SELECT *
FROM loan
INNER JOIN
(SELECT max(id) max_id
FROM loan
GROUP BY employee_id) x ON x.max_id = loan.id
group by employee_id;
I have to mention that your DB table design without primary key isn't well designed: https://i.stack.imgur.com/DTYO8.png
If only the row containing the last loan_id is required than a correlated sub query is what you want
SELECT *
FROM single_roww1 SR
WHERE LOAN_ID = (SELECT MAX(LOAN_ID) FROM single_roww1 WHERE EMPLOYEE_ID = SR.EMPLOYEE_ID);
With a correlated subquery in the WHERE clause:
SELECT s.employee_id, s.employee_name, s.department_name,
s.designation_name, s.PF_type, s.PF_number, s.Opening_balance,
s.Loan_id, s.loan_date, s.loan_amount
FROM single_roww1 s
WHERE s.Loan_id = (SELECT MAX(Loan_id) FROM single_roww1 WHERE employee_id = s.employee_id)
last taken loan value and date
You seem to want:
SELECT sr.*
FROM single_roww1 sr
WHERE sr.loan_date = (SELECT MAX(sr2.load_date)
FROM single_roww1 sr2
WHERE sr2.employee_id = sr.employee_id
);
This assumes shat loan_date has a proper date/time type in the database (despite what the data in the image looks like).
For performance, you want an index on (employee_id, load_date).
Note that if an employee has multiple loans on the same date, this will retrieve the last one.
Related
Actually, i did counted distinct empid rows according to dates. But the problem is i get only one empid record of that specific dates.Please let me know how to get all empid records. Here is my sql query.
$sql = "
SELECT COUNT(DISTINCT subcount.empid) AS CountOf
, subcount.name
, subcount.date
, subcount.empid
, calendar.cdate
FROM subcount
, calendar
WHERE subcount.date = calendar.cdate
GROUP
BY subcount.date
";
Here is sql database.
For example, When you look at 2020-11-10 there are two empid with 10 and 7.
When i tried to get both records i get only empid 10 record or 7 record, though i need both record counts:
Here is the output:
Please help me on this.
I think what you are asking is to get list of employees with count of their submissions on a given date, this could show do it:
SELECT cnt.empid AS EmpId
, sc.Name
, cnt.`date` AS Timestamp
, cnt.CountOf AS SubmissionCount
FROM subcount AS sc
INNER JOIN
(
SELECT subcount.empid
subcount.`date`,
count(*) AS CountOf
FROM subcount
INNER JOIN calendar
ON subcount.`date` = calendar.cdate
GROUP BY
subcount.`date`, subcount.empid
) AS cnt
ON sc.empid == cnt.empid
It uses nested SELECT with GROUP BY to calculate count per employee (empid) and date (not only employee). Outer SELECT join nested SELECT to get subcount.Name piece of data which isn't retrieved in nested SELECT so it needs to be retrieved using outer SELECT.
GROUP BY ___ means result rows per ___. If you group by employee ID, you get one row per employee ID. If you want one row per employee ID and date, group by employee ID and date.
SELECT any_value(s.name), s.`date`, s.empid, c.cdate, count(*)
FROM subcount s
JOIN calendar c on c.cdate = s.`date`
GROUP BY s.`date`, s.empid
ORDER BY s.`date`, s.empid;
I expect a calendar table to have one row per date, so there is exactly one cdate for a result row. The name, however, can be different from row to row, so we must tell the DBMS, which to pick. With ANY_VALUE I tell it that I don't care which.
I have a Ms Access table with four columns; PledgeID, Ref, Paid, and Balance. One PledgeID may have several records. I need a query that will help me get the sum of the Balance for ONLY the last record of each PledgeID. The last PledgeID will be the one with the highest ref. I have attached a photo of the table for easy reference.
Click To View Image
You could use this SQL:
SELECT T2.PledgeID
, T2.REF
, T2.Balance
FROM (
SELECT PledgeID
, MAX(Ref) AS REF_RETURN
FROM MyTable
GROUP BY PledgeID
) T1 INNER JOIN MyTable T2 ON T1.REF_RETURN = T2.REF
It would probably be easier to limit the Ref field to just numeric - 1, 2 rather than PID/2018/00007-1 & PID/2018/00007-2.
You could use a subquery to find the latest balance per PledgeID and sum these balances:
SELECT Sum(Balance)
FROM Balances
WHERE Ref = (SELECT Max(Ref) FROM Balances AS b WHERE PledgeID = Balances.PledgeID);
Looking at your sample table, the result seems to be 0.00.
SELECT *
FROM table
INNER JOIN
(SELECT itemno, MAX(last_updated) as TopDate
FROM table
WHERE userID = 'user'
GROUP BY itemno) AS EachItem ON
EachItem.TopDate = table.last_updated
AND EachItem.itemno = table.itemno
I have taken the solution above from a previous post and modified it to work with one of the functions that I have created but I now want to use this same query but adapt it to order the result by max(last_updated) (which is a timestamp in my table) and also max(qty_sold).
Basically I have multiple duplicates of itemnos in the table but only want to return the rows with the latest date and highest qty_sold for every row where a certain user ID is specified.
Many thanks in advance, I have spent hours searching and can't figure this out as I am fairly new to mysql.
Solved my own question after more trying by adding ORDER BY qty_sold DESC to the end.
SELECT *
FROM table
INNER JOIN
(SELECT itemno, MAX(last_updated) as TopDate
FROM table
WHERE userID = 'user'
GROUP BY itemno) AS EachItem ON
EachItem.TopDate = table.last_updated
AND EachItem.itemno = table.itemno
ORDER BY qty_sold DESC
I'm trying to create query that will show me table of stock, name of the stock, id, date, url, price and list of prices from the last 2 weeks.
For the 14 days history I used sub-query with group_concat on the select.
But when I use group_concat it's return all results and ignore my limit, so I created another sub-query that will be the 14 prices and the group_concat will make it a list.
The table 'record_log' is records for all stocks:
parent_stock_id - the actual stock this line belongs
price - the price
search_date - date of the price
The second table is 'stocks':
id - id of the stock
name, market_volume....
Here is the problem:
In the sub-sub-query (last line of the SELECT), when i'm filtering parent_stock_id=stocks.id he don't recognize the stocks.id because it belongs to the main query.
How can I take the stock_id from top and pass it to the sub-sub-query? or maybe another idea?
SELECT
stocks.id AS stock_id,
record_log.price AS price,
record_log.search_date,
(SELECT GROUP_CONCAT(price) FROM (SELECT price FROM record_log WHERE parent_stock_id=stocks.id ORDER BY id DESC LIMIT 14) AS nevemind) AS history
FROM stocks
INNER JOIN record_log ON stocks.id = record_log.parent_stock_id
WHERE
record_log.another_check !=0
Thank you!
--- I'm are not really using it for stocks, it's just was the easiest way to explain :)
One method is to use substring_index() and eliminate the extra subquery:
SELECT s.id AS stock_id, rl.price AS price, rl.search_date,
(SELECT SUBSTRING_INDEX(GROUP_CONCAT(price ORDER BY id DESC), ',', 14)
FROM record_log rl2
WHERE rl2.parent_stock_id = s.id
) AS history
FROM stocks s INNER JOIN
record_log rl
ON s.id = rl.parent_stock_id
WHERE rl.another_check <> 0;
Note that MySQL has a settable limit on the length of the group_concat() intermediate result (group_concat_max_len). This parameter is defaulted to 1,024.
What I'm looking to do is this...
I have a database that logs changes in the status of a record...
For example, it may be set as "inactive" then, a later row might reactivate the record...
1 Company1 Active
2 Company2 Active
3 Company1 Inactive
4 Company1 Active
The query needs to look for currently active results... and should return two records... (one for Company1 and one for Company2.)
I need to return only records that are CURRENTLY active.
This query does part of it...
SELECT id, gid, status
FROM companies
GROUP BY gid
HAVING status = 'Active'
ORDER BY id
But it doesn't look for results to return based on the last record...
What I am basically looking at is how to incorporate something that would check only the the most recent record like "LIMIT 1,1" with "ORDER BY id DESC) within each group... I have no idea how to incorporate it into the query.
Update I've got it down to this so far... Based on an answer but it's bringing back the last row of each group whether it is currently active or not...
select t.*
from (
select status, max(id) as id
from companies
group by gid
having status = 'Active'
) active_companies
inner join companies t on active_companies.id = t.id
If your IDs are always in ascending order, this will select the most recent ID for every company:
SELECT MAX(id), gid
FROM companies
GROUP BY gid
and this will return all the records that you need:
SELECT companies.*
FROM companies INNER JOIN (SELECT MAX(id) m_id
FROM companies
GROUP BY gid) m
ON companies.id = m.m_id
WHERE
status = 'Active'
You might also be tempted to use this little trick:
SELECT *
FROM (SELECT * FROM companies ORDER BY id DESC) t
GROUP BY gid
HAVING status='Active';
but please don't! It usually/most always work, it looks cleaner and is often faster, but relies on an undocumented behaviour, so it is not guaranteed that you will always get the correct result.
Please see fiddle here!
The following query returns the current status for each company, using a MySQL trick:
select gid, substring_index(group_concat(status order by id desc), ',', 1) as status
from companies
group by gid;
If you want only the ones that are currently active:
select gid
from companies
group by gid
having 'active' = substring_index(group_concat(status order by id desc), ',', 1)
Let's split the problem into two smaller ones:
First, you want to get the most recent entry from each group:
select max(id)
from companies
group by gid;
Next, you want to have only entries (which are last entries) and which are active:
select t.*
from companies t
inner join (
select max(id) as id
from companies
group by gid
) last_entries
on t.id = last_entries.id
where t.status = 'Active';
Try a subselect get records where status = 'Active' and order by id (which i assume is auto-increment ) desc then in parent select do group by
SELECT t.* FROM (
SELECT *
FROM companies
WHERE `status` = 'Active'
ORDER BY id DESC
) t
GROUP BY t.gid