How to get last row of repeating column in php mysql - php

I have a table as follow. I want to run a query to select the data from the table using php in which if date column is repeated then I want to take only last row of that date
id Date start end publish
1 04-Nov-2015 1000 1300 0
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
like for the below table, When I run the query then the result should come:
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
When I run the query
$select = mysql_query("select * from `entry` Group by `date`") or die(mysql_error());
Then It shows the first row of repeating table, What should I modify in the query that the result should show the last row of repeating colum

Select * from (Select * from entry order by date,id desc) x group by x.date

You can do this with this approach:
$select = mysql_query("select * from `entry` Group by `date`" ORDER BY id DESC LIMIT 1) or die(mysql_error());

Try inner query, I'm not sure following will work exactly as I cant test that now, but for getting result you have to use inner query. Inner query help me to get expected result in my case.
SELECT *
FROM entry p
WHERE id =
(SELECT max(id) FROM entry p2
WHERE p2.id = p.id)
GROUP BY p.date
ORDER BY p.id DESC;

This query will work for you:
create TABLE test (id INT PRIMARY KEY, tdate DATE, start INT);
SELECT t1.* FROM test as t1
LEFT JOIN test as t2
ON (t1.tdate = t2.tdate AND t1.id < t2.id)
WHERE t2.id IS NULL;

Try this query :-
select * from( select * from entry order by id DESC ) new Group by date

Related

Mysql Query search by latest date with group by

This is my table structure
and this is my dataset
What I want is query that gets data ordered by date desc and group by id_patient
so the result in the dataset example should be like this:
I would go with limit clause with subquery since you have PK :
select *
from table t
where id = (select t1.id
from table t1
where t1.id_patient = t.id_patient
order by t1.date desc
limit 1
);
However, if single patient has multiple same dates then this would produce only single records based on date.
SELECT * from rdv a JOIN (SELECT id_patient,MAX(date) date FROM rdv GROUP by id_patient ) b on a.id_patient = b.id_patient and a.date = b.date
If you want the latest record for each patient, then you are not looking for an aggregation. I would often approach this with a correlated subquery:
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.id_patient = t.id_patient);
SELECT *
FROM table
GROUP BY group by id_patient
ordered by DATE(date) desc;

Alternative of NOT EXISTS in MySQL as query is taking time to execute with NOT EXISTS

Dummy table:
id FileName DateLastSaved
1 Marium.doc 2015-01-01
2 Amna.doc 2016-01-01
3 Marium.doc 2016-01-01
I want the query to return such rows where FileName is unique in the whole table. Rows should be returned for particular date range.
Suppose date ranges are of 2016 only, so third row should not be returned as FileName is not unique.
The query that I have created is:
$presentquery="SELECT * FROM InitialLog i WHERE MDid='$MDid' AND
(DateLastSaved>='$firstdate' AND DateLastSaved<='$presentdate') AND NOT
EXISTS (SELECT id FROM InitialLog i2 WHERE i2.id<i.id AND i.FileName=i2.FileName )";
(Where $firstdate and $presentdate are 2 dates for date ranges)
The query is returning the accurate results but it's taking time to execute. Is there any other way that I can rewrite this query??
(I have table with many rows)
I put this query together and it returns the results very quickly.
Select *
FROM foo
Where (`datelastsaved` > '2015-12-31' && `datelastsaved` < '2017-01-01')
AND `filename` NOT IN (
Select `filename`
FROM foo
GROUP BY `filename`
HAVING COUNT(*) > 1);
The first part is your normal select statement with the where clauses to filter on the dates.
The second part is the NOT IN where the select statement finds all of the ones with duplicate filenames.
Select `filename` FROM foo GROUP BY `filename` HAVING COUNT(*) > 1)
You can get the same logic using a LEFT JOIN and looking for nulls, that is,
$presentquery = "SELECT DISTINCT i.* FROM InitialLog i
LEFT JOIN InitialLog i2 ON i2.id<i.id AND i.FileName=i2.FileName
WHERE i.MDid='$MDid'
AND i.DateLastSaved>='$firstdate'
AND i.DateLastSaved<='$presentdate'
AND i2.id IS NULL";
This way you are doing a single join rather than subquerying against each value in i.
It looks like you are trying to get the data associated with the first occurrence of each file name, this should work:
SELECT *
FROM InitialLog i
WHERE MDid='$MDid'
AND DateLastSaved>='$firstdate'
AND DateLastSaved<='$presentdate'
AND id IN (SELECT MIN(id) FROM InitialLog GROUP BY FileName)
;
Alternatively, you can do a JOIN with the same subquery instead:
SELECT i.*
FROM InitialLog AS i
INNER JOIN (SELECT MIN(id) AS id
FROM InitialLog
GROUP BY FileName
) AS firsts USING (id)
WHERE i.MDid='$MDid'
AND i.DateLastSaved>='$firstdate'
AND i.DateLastSaved<='$presentdate'
;

How can I select the largest value in one column, and then the largest value in the other column?

I have a table looking like this:
ID quote_no version
------------------------
1 123 1
2 123 2
3 123 1
4 123 2
5 321 1
6 321 1
I would like to select the latest version of each quote, and if theres multiple records of that version i would like to get the row with the highest ID.
(in this case the query should produce the following result):
ID quote_no version
------------------------
4 123 2
6 321 1
How could I do that in a query?
You can approach this with a not exists clause:
select t.*
from table t
where not exists (select 1
from table t2
where t2.quote_no = t.quote_no and
(t2.version > t.version or
t2.version = t.version and t2.id > t.id
)
);
If you just want the one with the highest id (which is also consistent with your results), you can do:
select t.*
from table t join
(select quote_no, max(id) as maxid
from table t
group by quote_no
) tt
on t.id = tt.maxid;
I would write a subquery that gets the largest version for each quote_no, like this:
SELECT quote_no, MAX(version) AS maxVersion
FROM myTable
GROUP BY quote_no;
And you can join that with your original table, and use another MAX() function to get the largest id:
SELECT MAX(m.id), m.quote_no, mt.maxVersion
FROM myTable m
JOIN(
SELECT quote_no, MAX(version) AS maxVersion
FROM myTable
GROUP BY quote_no) mt ON mt.quote_no = m.quote_no AND mt.maxVersion = m.version
GROUP BY m.quote_no;
Works fine in SQL Fiddle.
The latest X records per group is a tough problem in MySQL, except when X is 1 as in your case. You can do it like this. For each quote, join all rows that have the same quote_no, but a greater version., or the same version but with a larger ID. Then you can apply a filter to only keep those rows that don't have a greater version:
SELECT
t1.*
FROM
YourTable t1
LEFT JOIN YourTable t2 ON
t2.quote_no = t1.quote_no AND -- Quote must match anyway
( t2.version > t1.version OR -- Version must be larger
( t2.version = t1.version AND -- Or if version is the same...
t2.ID > t1.ID ) -- ID must be larger.
WHERE
t2.quote_no IS NULL
Try something like that :
SELECT t2.*
FROM QuoteTable t2
JOIN (SELECT
MAX(ID) AS t1.LatestId,
quote_no
FROM QuoteTable t1
GROUP BY quote_no)
ON t2.id = t1.LatestId;
EDIT : the Parent SELECT statement prevents version number error.

MySQL: Query design issue

My tables are like this:
Table 1 (students)
Table 2 (results)
I want to select all students from Table 1 students who have 4 results in the results table. I tried this query, but with no success:
SELECT *
FROM students
WHERE gender = 'm'
AND (SELECT COUNT( result ) AS count
FROM results
INNER JOIN students ON results.stuID = students.stuID
WHERE result !=0
) =4
ORDER BY rank ASC
You can rewrite your query by using join and HAVING clause to check the count for each student group ,This can be done without using the subquery which sometimes affects on performance
SELECT s.*,COUNT(*) AS count
FROM students s
INNER JOIN results r ON r.stuID = s.stuID
WHERE r.result !=0
GROUP BY s.stuID
HAVING count =4
ORDER BY s.rank ASC
um, that's a little convoluted.
the where clause should come after the subquery, and the subquery still needs to be JOINed back to the main query.
something like
SELECT * FROM students
INNER JOIN (SELECT COUNT(result),results.stuID as count FROM results WHERE result != 0) as result_count
ON result_count.stuID = students.stuID
WHERE result_count.count =4 AND students.gender = 'm'
ORDER BY rank ASC
You have to use alias for table also -
SELECT *
FROM students as a
WHERE gender = 'm'
AND (SELECT COUNT(result) AS count
FROM results as b
WHERE b.stuID = a.stuID AND
(result!=0 OR result IS NOT NULL OR result!='')
) = 4
ORDER BY rank ASC

Advanced query with mysql: variables/subqueries?

I want to get the latest 5 messages in the inbox.
To get the 5 latest IDs i need to use this:
SELECT
MAX(id)
FROM
samtaler
WHERE
brukerid_mottaker = 1
GROUP BY brukerid_avsender
ORDER BY id DESC
LIMIT 5
This return the correct ID's I need. But in the same query i want to select data from the same table, the row that got the id that returned from this query above.
I have tried out some things, variables and self-join but no luck:
select
p2.title,
p2.message,
#a:=max(p1.id)
from
samtaler p1
join samtaler p2
on (#a = p2.id)
where
p2.brukerid_mottaker = 1
group by p2.brukerid_avsender
order by p2.id DESC
limit 5
Why isnt this working?
This is the current data in the database:
I want to return in this case, row 13 and 4. Sorry for bad english.
Join against a subquery, instead of a plain self join. An IN() clause won't work since LIMIT cannot be used inside an IN(). It should work in the joined subquery though:
SELECT
p1.title,
p1.message,
p2.id
FROM
samtaler p1
JOIN (
SELECT MAX(id) AS id
FROM
samtaler
WHERE
brukerid_mottaker = 1
GROUP BY brukerid_avsender
ORDER BY id DESC
LIMIT 5
) p2 ON p1.id = p2.id
By this method, there is no need for variables.

Categories