How to Retrieve Last Record in mysql? - mysql

I have a table name Data with fields
Surmane, Name, Timestamp, PaidMoney, ChangAmmount, Address, Store
I want to have as result of a query the last record (DESC Timestamp Limit 1) of each person (group by Surname, Name) with the PaidMoney,ChangeAmmount, Address, Store
For example the result must be
Jones, Jim, 1290596796, 220.00, 0.25, 5th Avenue 120, Some Store1
Kojak, Ian, 1290596890, 1000.00, 50.25, Derek Avenue 1020, Some Store2
For each combination of Surname, Name must present the last record.
I try to do this with:
select `Surname`,
`Name`,
max(date_format(from_unixtime(`Timestamp`),'%Y/%m/%d - %T')) AS `dateTime`,
`PaidMoney`,
`ChangAmmount`,
`Address`,
`Store`
from `Data`
group by `Surname`, `Name`;
No good cause this doesn't show correct data.....
Please Help...
Thank you...

select t1.surname,
t1.name,
from_unixtime(t1.timestamp,'%Y/%m/%d - %T') as datetime,
t1.PaidMoney,
t1.ChangAmmount,
t1.Address,
t1.Store
from table as t1
inner join (select concat_ws(' ',name,surname) as n,max(timestamp) as timestamp
from table
group by name,surname) as t2
on t1.timestamp = t2.timestamp and concat_ws(' ',t1.name,surname) = t2.n
Your table contains redundant datas of names and surnames.
It would be better if you put these datas in another table and refer to them using people id.
Moreover without an id, the use of concat will slow down the join performance, even if you would have an index.
edit.
create view my_view as
select * from table t1
where timestamp = (select max(timestamp) from table as t2
where concat_ws(' ',t1.name,t1.surname) = concat_ws(' ',t2.name,t2.surname))

You should add order by timestamp DESC to your query and change the max(...) part to timestamp.

You could do a subquery (ie. a nested SELECT) to get the max(date stuff) for each person, but that wouldn't be very efficient, according this page, which suggests another way that might be helpful:
http://dev.mysql.com/doc/refman/4.1/en/example-maximum-column-group-row.html

Related

Need list of data using DISTINCT, COUNT, MAX

The table structure is as below,
My first SQL query is as below,
SELECT DISTINCT(IndustryVertical)
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City
ORDER
BY `IndustryVerticalCount` DESC
by running the above query I'm getting the below,
What I'm trying to achieve is to get the List of all the DISTINCT CITY with ONLY ONE MAX(IndustryVerticalCount) and IndustryVertical.
Tried several things with no hope.
Anyone, please guide me.
There're several records in each City values. what I'm trying to achieve is that getting,
All the distinct City Values
The MAX COUNT of industryVertical
Name of industryVertical
The record I'm getting is as below,
What I'm trying to get,
The above record is reference purpose. Here, you can see only distinct city values with only one the vertical name having max count.
Since you are using group by, it will automatically select only distinct rows. Since you are using group by on two columns, you will get rows in which only combination of both columns is distinct.
What you now have to do is use this resulting table, and perform a query on it to find the maximum count grouped by city.
SELECT IndustryVertical, IndustryVerticalCount, City from
( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl where IndustryVerticalCount IN (Select max(IndustryVerticalCount) from ( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl2 where tbl.City=tbl2.city)
This may not be the most efficient method, but I think it will work.
How about this? I think it should be worked:
DECLARE #DataSet TABLE (
City VARCHAR(50),
IndustryVertical VARCHAR(50),
IndustryVerticalCount INT
)
INSERT INTO #DataSet SELECT 'Bangalore', 'Consumer Internet', 279
INSERT INTO #DataSet SELECT 'Bangalore', 'Technology', 269
INSERT INTO #DataSet SELECT 'Bangalore', 'Logistics', 179
INSERT INTO #DataSet SELECT 'Mumbai', 'Technology', 194
INSERT INTO #DataSet SELECT 'Mumbai', 'Consumer Internet', 89
SELECT
table_a.*
FROM #DataSet table_a
LEFT JOIN #DataSet table_b
ON table_a.City = table_b.City
AND table_a.IndustryVerticalCount < table_b.IndustryVerticalCount
WHERE table_b.IndustryVerticalCount IS NULL
I think you simply want a HAVING clause:
SELECT r.IndustryVertical,
COUNT(*) AS IndustryVerticalCount,
r.City
FROM records r
WHERE r.City <> ''
GROUP BY r.IndustryVertical, r.City
HAVING COUNT(*) = (SELECT COUNT(*)
FROM records r2
WHERE r2.City = r.City
ORDER BY COUNT(*) DESC
LIMIT 1
)
ORDER BY IndustryVerticalCount DESC;

MaraiDB / MySQL Insert Into Table From Select Query But On Duplicate Key Use Data From Select Query

I have created table A as follows:
I put in the data above using a simple INSERT INTO and SELECT statement. Now that the source data is corrected, I want to used the INSERT INTO, SELECT, ON DUPLICATE KEY UPDATE, but when I run the code, the 0's and NULL that you see above does not update to the new value.
Here is my code
INSERT INTO
TABLEA (uniqueid, year, month, costcentre, amount)
SELECT
SS.uniquekey, SS.year, SS.month, SS.source, SS.totalamount
FROM
(SELECT
uniquekey, `YEAR`, `MONTH`, SOURCE, totalamount
FROM
TABLEB
UNION ALL
SELECT
uniquekey, `YEAR`, `MONTH`, SOURCE, totalamount
FROM
TABLEC
) as SS
ON DUPLICATE KEY
UPDATE
TABLEA.YEAR = VALUES(SS.year),
TABLEA.MONTH = VALUES(SS.month),
TABLEA.COSTCENTRE = VALUES(SS.SOURCE),
TABLEA.AMOUNT = VALUES(SS.TOTALAMOUNT)
;
So the answer I am looking for, is:
I want TABLEA to have a line for each UNIQUE that is in the SELECT query.
If TABLEA contains the same UNIQUEID as the SELECT, then I want it to update the YEAR, MONTH, COSTCENTRE, AMOUNT from the SELECT query
Converted my comment to an answer.
I believe that it should be ON DUPLICATE KEY UPDATE YEAR = VALUES(YEAR) - i.e. you should refer to the column names of TABLEA only

I want to pull distinct values for 2 columns in the same table and associated unique value columns for these unique values in SQL

The table is something like:
User_id Bidid timestamp ... (about 25-30 more columns)
How do I pull all the distinct user ids with all the distinct Bidid's associated with them and also the timestamp which is unique to each Bidid?
select distinct comes to mind:
select distinct User_id, Bidid, timestamp
from t;
I think this could be idea you are looking for, it depends of the version SQL/environment/etc:
SELECT USER_ID, BIDID, TIMESTAMP, ...
FROM THE_TABLE
WHERE BIDID=(SELECT DISTINCT BIDIT FROM THE_TABLE)
or
SELECT USER_ID, BIDID, TIMESTAMP,..
FROM THE_TABLE
WHERE BIDID IN (SELECT DISTINCT BIDIT FROM THE_TABLE)

MySQL: Returning first occurrence or record by date

I'm trying return the first occurrence of an ID, by primary key and date (from timestamp column). Here is an example of how the data would look:
In this example, the following ID's should be returned:
111, 333, 444
Note: I want to de-dupe by email / date (returning id from min timestamp). 333 and 444 are returned, because while tied to same email, they have different date. 222 isn't returned, because tied to same email / date as 111, where 111 has earlier timestamp
Based on your comment, you can do this by getting the minimum timestamp for each email/date combination. Then you can join back to get additional information from the row:
select t.*
from table t join
(select email, min(timestamp) as mints
from table t
group by email, date(timestamp)
) tt
on t.email = tt.email and t.timestamp = tt.mints;
Try this:
create table your_table(id int, email varchar(10), t timestamp)
;
insert into your_table values
(111,'a#a','2015-01-01 00:00:00'),
(222,'a#a','2015-01-01 10:00:00'),
(333,'b#b','2015-01-01 08:00:00'),
(444,'b#b','2015-02-01 09:00:00')
select substring_index(ids,',',1)
from (
select email,
date(t) as dt,
group_concat(id order by t) as ids
from your_table
group by email,date(t)
order by email,date(t)
) as tmp
SQL FIDDLE DEMO

PHP SQL - Advanced delete query

I have a table with 3 columns: id, date and name. What I am looking for is to delete the records that have a duplicate name. The rule should be to keep the record that has the oldest date. For instance in the example below, there is 3 records with the name Paul. So I would like to keep the one that has the oldest date (id=1) and remove all the others (id = 4 and 6). I know how to make insert, update, etc queries, but here I do not see how to make the trick work.
id, date, name
1, 2012-03-10, Paul
2, 2012-03-10, James
4, 2012-03-12, Paul
5, 2012-03-11, Ricardo
6, 2012-03-13, Paul
mysql_query(?);
The best suggestion I can give you is create a unique index on name and avoid all the trouble.
Follow the steps as Peter Kiss said from 2 to 3. Then do this
ALTER Table tablename ADD UNIQUE INDEX name (name)
Then Follow 4 Insert everything from the temporary table to the original.
All the new duplicate rows, will be omitted
Select all the records what you want to keep
Insert them to a temporary table
Delete everything from the original table
Insert everything from the temporary table to the original
Like Matt, but without the join:
DELETE FROM `table` WHERE `id` NOT IN (
SELECT `id` FROM (
SELECT `id` FROM `table` GROUP BY `name` ORDER BY `date`
) as A
)
Without the first SELECT you will get "You can't specify target table 'table' for update in FROM clause"
Something like this would work:
DELETE FROM tablename WHERE id NOT IN (
SELECT tablename.id FROM (
SELECT MIN(date) as dateCol, name FROM tablename GROUP BY name /*select the minimum date and name, for each name*/
) as MyInnerQuery
INNER JOIN tablename on MyInnerQuery.dateCol = tablename.date
and MyInnerQuery.name = tablename.name /*select the id joined on the minimum date and the name*/
) /*Delete everything which isn't in the list of ids which are the minimum date fore each name*/
DELETE t
FROM tableX AS t
LEFT JOIN
( SELECT name
, MIN(date) AS first_date
FROM tableX
GROUP BY name
) AS grp
ON grp.name = t.name
AND grp.first_date = t.date
WHERE
grp.name IS NULL
DELETE FROM thetable tt
WHERE EXISTS (
SELECT *
FROM thetable tx
WHERE tx.thename = tt.thename
AND tx.thedate > tt. thedate
);
(note that "date" is a reserver word (type) in SQL, "and" name is a reserved word in some SQL implementations)