I have below table
+--------------+-----------+
| serial no | isNew |
+--------------+-----------+
| 630401A | 2014 |
| 630401B | 2014 |
| 630401A | 2013 |
| 630401B | 2013 |
| 630401C | 2013 |
+--------------+-----------+
Now the thing is I want to select records as per isNew column. As you can see that serial no is same and isNew is different in 2 cases and in on case there is only record for serial number.
So I want output like
+--------------+-----------+
| serial no | isNew |
+--------------+-----------+
| 630401A | 2014 |
| 630401B | 2014 |
| 630401C | 2013 |
+--------------+-----------+
I hope I am very clear to display my table and result I want.
Thanks for your help in advance!
select * from TABLENAME group by serialno order by isNew DESC
select `serial no`, max(isNew) from table group by `serial no`
GROUP BY statement is used in conjunction with the aggregate functions to group the result-set
Use group by serialno
select * from table group by serialno order by isNew DESC
Related
I have a MySQL table:
+======+=========+============+======+======+
| name | surname | other_name | year | date |
+======+=========+============+======+======+
| John | Foo | NULL | 2000 | 2017 |
+------+---------+------------+------+------+
| John | Foo | Bar | 2000 | 2018 |
+------+---------+------------+------+------+
| John | Bar | NULL | 2000 | 2018 |
+------+---------+------------+------+------+
| John | Bar | Bar | 2000 | 2018 |
+------+---------+------------+------+------+
| John | Foo | NULL | 1990 | 2018 |
+------+---------+------------+------+------+
I'm trying to group the records for same person. Same person is identified by name, surname and year of birth.
One can however change his surname (Foo -> Bar). Then the old rows' other_name column should be updated with the new name. Unfortunately the data I have are incomplete and when one changed his name, the other_name might have been updated, but it also might not.
I can easily group by the three basic columns.
What I need to do as well though is to cross compare the surname and other_name and if they match and so do the name and year columns, group them under the most recent surname (decided by date when the row was recorded).
The final print result should look like this:
+======+===========+======+
| name | surname | year |
+======+===========+======+
| John | Bar (Foo) | 2000 |
+------+-----------+------+
| John | Foo | 1990 |
+------+-----------+------+
I realize it's rather a complex task for an SQL query. So if you have a simpler solution accomplished in the program (PHP), I would appreciate it as well.
Hmmm . . . This does what you want in the limited case that surnames are only changed once:
select t.name, t.year, group_concat(distinct t.surname) as surnames
from t left join
t tother
on t.surname = tother.other_name and t.name = tother.name and t.year = tother.year
group by t.name, t.year, coalesce(tother.surname, t.surname);
Here is a db<>fiddle (it uses Postgres because I find that easier to set up but all is the same except the group_concat()).
Example my_table
ID | Name | Date
--------------------------
12 | John | 123456789
13 | Mike | 987654321
...
29 | Rick | 123498765
30 | Adam | 987651234
show output result like this
Month | Count
--------------------------
3 | 5 |
6 | 8 |
How can I do this with PHP?
You can do this using MySQL Query as below.
SELECT MONTH(FROM_UNIXTIME(`Date`)) `Month`
,COUNT(ID)
FROM my_table
GROUP BY `Month`;
Since post tagged codeigniter
This is codeigniter way:
$query = $this->db->select("month(from_unixtime(`Date`)) as `month`, count(1) as `count`",FALSE)
->group_by("month");
->get("your_table");
I'm having a hard time getting results from a DB the way I need them, this is my table:
+----+---------------------+---------------------+-----------+------------+--------+
| id | opendate | closedate | openprice | closeprice | sameid |
+----+---------------------+---------------------+-----------+------------+--------+
| 1 | 2015-09-20 19:17:52 | NULL | 10 | NULL | 20 |
| 2 | NULL | 2015-09-20 20:17:00 | NULL | 35 | 20 |
| 3 | 2015-09-15 19:17:52 | NULL | 15 | NULL | 10 |
| 4 | NULL | 2015-09-16 20:17:00 | NULL | 25 | 10 |
+----+---------------------+---------------------+-----------+------------+--------+
I need to get all the rows grouped by the column sameid like this:
+----+---------------------+---------------------+-----------+------------+--------+
| id | opendate | closedate | openprice | closeprice | sameid |
+----+---------------------+---------------------+-----------+------------+--------+
| 1 | 2015-09-20 19:17:52 | 2015-09-20 20:17:00 | 10 | 35 | 20 |
| 3 | 2015-09-15 19:17:52 | 2015-09-16 20:17:00 | 15 | 25 | 10 |
+----+---------------------+---------------------+-----------+------------+--------+
And this is what I have tried so far:
(SELECT * FROM table WHERE opendate >= '2015-08-08 00:00:01') UNION (SELECT * FROM table WHERE closedate <= '2015-10-15 23:59:59')
I can get all the rows but I can not fin a way to group them by sameid, I tried using GROUP BY sameid without success.
Hope you guys can help me
Thank you
UPDATE
The table was designed that way long ago, (not by me) and there is too much information stored, I'm not allowed to redesign the DB schema either.
If your table format exactly what you describe, then this should work:
SELECT id, MAX(opendate), MAX(closedate), MAX(openprice), MAX(closeprice), sameid FROM table GROUP BY sameid;
However, I think you should redesign your database schema, seperate open info and close info into 2 rows (they could be in 2 tables or in same table). It's would be better for you to work with rather than trying some workaround.
Regards,
Try this
SELECT t1.opendate, t2.closedate, t1.openprice, t2.closeprice FROM `table` t1 JOIN `table` t2 ON t2.sameid = t1.sameid WHERE t1.opendate >= '2015-08-08 00:00:01' AND t2.closedate <= '2015-10-15 23:59:59' AND t1.opendate IS NOT NULL AND t2.closedate IS NOT NULL
This will produce your exact output.
SELECT
MIN(id) as id,
MAX(open_date) as open_date,
MAX(close_date) as close_date,
MAX(open_price) as open_price,
MAX(close_price) as close_price,
sameid
FROM
`table`
GROUP BY
sameid
ORDER BY id ASC
I have two table tbl_issue_log, tbl_magazine_issue
tbl_issue_log
============
+----------+--------+--------+-----------+---------------------+
| issue_id | mag_id | log_id | operation | updated_time |
+----------+--------+--------+-----------+---------------------+
| 2 | 1 | 1 | 1 | 2014-01-30 21:29:44 |
| 3 | 4 | 1 | 1 | 2015-01-30 21:29:44 |
| 2 | 1 | 1 | 3 | 2015-01-31 21:29:44 |
+----------+--------+--------+-----------+---------------------+
tbl_magazine_issue
=================
+----------+-------------+-------------+------------------+------------+------------+-------------------+---------------+
| ISSUE_ID | ISSUE_NAME | MAGAZINE_ID | COVER_PAGE_THUMB | FROM_DATE | TO_DATE | issue_description | login_page_no |
+----------+-------------+-------------+------------------+------------+------------+-------------------+---------------+
| 2 | test issue | 1 | cover page | 2014-01-30 | 2015-01-30 | sdssdg fsdf | 20 |
| 3 | test issue1 | 4 | cover page1 | 2014-01-30 | 2015-01-30 | sdssdg fsdf | 20 |
+----------+-------------+-------------+------------------+------------+------------+-------------------+---------------+
in tbl_issue_log contain multiple records for same issue id. i want only one issue at a time
and this must latest updated time.
My query is this
SELECT
`tbl_issue_log`.`operation`,
`tbl_magazine_issue`.`ISSUE_ID`,
`tbl_magazine_issue`.`ISSUE_NAME`,
`tbl_magazine_issue`.`MAGAZINE_ID`,
`tbl_magazine_issue`.`COVER_PAGE_THUMB`,
`tbl_magazine_issue`.`FROM_DATE`,
`tbl_magazine_issue`.`TO_DATE`,
`tbl_magazine_issue`.`issue_description`,
`tbl_magazine_issue`.`login_page_no`
FROM
`tbl_issue_log`
LEFT JOIN
`tbl_magazine_issue` ON tbl_magazine_issue.ISSUE_ID = tbl_issue_log.issue_id
WHERE
(tbl_issue_log.mag_id = '1')
AND (tbl_magazine_issue.ISSUE_STATUS = 3)
AND (tbl_issue_log.updated_time > '2014-02-25 00:42:22')
GROUP BY tbl_issue_log.issue_id
ORDER BY tbl_issue_log updated_time DESC;
Here i got issue id based output . But not getting the latest updated timeed record.
If any one about this please help me.
Try this
SELECT * FROM
(SELECT
`tbl_issue_log`.`operation`,
`tbl_magazine_issue`.`ISSUE_ID`,
`tbl_magazine_issue`.`ISSUE_NAME`,
`tbl_magazine_issue`.`MAGAZINE_ID`,
`tbl_magazine_issue`.`COVER_PAGE_THUMB`,
`tbl_magazine_issue`.`FROM_DATE`,
`tbl_magazine_issue`.`TO_DATE`,
`tbl_magazine_issue`.`issue_description`,
`tbl_magazine_issue`.`login_page_no`
FROM
`tbl_issue_log`
LEFT JOIN
`tbl_magazine_issue` ON tbl_magazine_issue.ISSUE_ID = tbl_issue_log.issue_id
WHERE
(tbl_issue_log.mag_id = '1')
AND (tbl_magazine_issue.ISSUE_STATUS = 3)
AND (tbl_issue_log.updated_time > '2014-02-25 00:42:22')
ORDER BY tbl_issue_log.updated_time DESC ) TEMP_TABLE
GROUP BY ISSUE_ID
Can you try changing order by clause as
ORDER BY tbl_issue_log.updated_time DESC;
Edit ---
As you are grouping on issue_id, mysql will select first row that matches the issue_id. The order by runs later which essentially does not return what you are looking for. You may need to use a subquery approach for this.
select some_table.* FROM
(
SELECT
MAX(tbl_issue_log.updated_time) AS updated_time,
`tbl_issue_log`.`operation`,
`tbl_magazine_issue`.`ISSUE_ID`,
`tbl_magazine_issue`.`ISSUE_NAME`,
`tbl_magazine_issue`.`MAGAZINE_ID`,
`tbl_magazine_issue`.`COVER_PAGE_THUMB`,
`tbl_magazine_issue`.`FROM_DATE`,
`tbl_magazine_issue`.`TO_DATE`,
`tbl_magazine_issue`.`issue_description`,
`tbl_magazine_issue`.`login_page_no`
FROM
`tbl_issue_log`
LEFT JOIN
`tbl_magazine_issue` ON tbl_magazine_issue.ISSUE_ID = tbl_issue_log.issue_id
WHERE
(tbl_issue_log.mag_id = '1')
AND (tbl_magazine_issue.ISSUE_STATUS = 3)
AND (tbl_issue_log.updated_time > '2014-02-25 00:42:22')
GROUP BY tbl_issue_log.issue_id
) some_table
ORDER BY some_table.updated_time DESC;
I have a table like the one below that currently has no values for rating, lib_id or votes.
library
id | title | year | rating | votes | lib_id |
---------------------------------------------
1 | book1 | 1999 | | | |
2 | book2 | 2010 | | | |
3 | book3 | 2009 | | | |
4 | book4 | 2007 | | | |
5 | book5 | 1987 | | | |
I then have the classifications table which looks like this.
classifications
id | title | year | rating | votes | lib_id |
---------------------------------------------
108 | book154 | 1929 | | | |
322 | book23 | 2011 | | | |
311 | book3 | 2009 | 9.3 | 4056 | 10876 |
642 | book444 | 2001 | | | |
533 | book567 | 1981 | | | |
It can happen that entries in the library table may not appear in the classifications table and vice-versa. There can also be the possibility that the title of the book is not unique. So what I want to do is go through each row in the library table, take the title and year columns, go to the classifications table and find the row that has these two values, retrieve the corresponding rating, votes and lib_id columns and update the entry in the library table.
I also want to use PDOs. Below is a non-working example of what i'm trying to achieve.
$update_vals_STH =
$DBH->prepare(
"UPDATE library SET lib_id=?, rating=?, votes=?
FROM (SELECT lib_id, rating, votes)
FROM classifications WHERE title=? AND year=?";
Any help would be appreciated. I'm quite new to MySQL and have been struggling with this one for a while.
You can join tables on update statement too.
UPDATE library a
INNER JOIN classifications b
ON a.title = b.title AND
a.year = b.year
SET a.rating = b.rating,
a.votes = b.votes,
a.lib_id = b.lib_id
// WHERE clause // if you want to have extra condition.
SQLFiddle Demo
UPDATE
For better performance, you need to add indexes on the following field.
ALTER TABLE library ADD INDEX (title, year);
ALTER TABLE classifications ADD INDEX (title, year);