Get latest rows from my sql database - mysql

I have a table where there in rows there is a column called version. I have 2 same entries with 1 column say abc(unique) in all the same rows. I have 2 rows as follows
ID|Name|Version|Unique_Id
-------------------------
1 |abc |1 | 23
2 |abc1|2 |23
3 |xyz |1 |21
4 |tre |1 |20
I want the result as
ID|Name|Version|Unique_Id
-------------------------
2 |abc1|2 |23
3 |xyz |1 |21
4 |tre |1 |20
I have tried grouping by Unique_Id, the result is as follows
ID|Name|Version|Unique_Id
-------------------------
1 |abc |1 | 23
3 |xyz |1 |21
4 |tre |1 |20
Following is the query I am using
SELECT * FROM test
group by Unique_Id
order by Version desc;
I want latest(top order by desc) of each each rows. Please help. How can i achieve that.

How about something like
INSERT INTO tbllogs
(logorigin,
logaction,
loguser,
logdate,
logoutcome)
VALUES (:origin,
:action,
:user,
:dt,
:outcome)
Use a sub select to determine the id and its max version number, then join back to the original table to retrieve the other values.
SQL Fiddle DEMO

Related

Counting whole DB while searching for specific SQL

I have a table in db for customers and their glasses
customer_inventory_tbl:
SELECT * FROM customer_inventory_tbl
+-------+-------+-------+
|id(pk) | name | spex |
+-------+-------+-------+
|1 |John |Oval |
|2 |Steve |Angular|
|3 |John |Aviator|
|4 |Kevin |Supra |
|5 |Jamie |Oval |
|6 |Ben |Supra |
+-------+-------+-------+
(this is a way more simplified version, haha)
If I view John's record it shows
SELECT * FROM customer_inventory_tbl WHERE name=John
+-------+-------+-------+
|id(pk) | name | spex |
+-------+-------+-------+
|1 |John |Oval |
|3 |John |Aviator|
+-------+-------+-------+
But what I require is when viewing John's record, it to show me
+-------+-------+-------+-----+
|id(pk) | name | spex |count|
+-------+-------+-------+-----+
|1 |John |Oval |2 |
|3 |John |Aviator|1 |
+-------+-------+-------+-----+
That "count" column is the number of records in the database that has "Oval" for instance.
Now that is easy enough, if I wanted to count every record in the db, but how do I get the count of all records whilst looking for a specific name.
I hope this makes sense
select c.*,
(
select count(1)
from customer_inventory_tbl
where spex = c.spex
) "count"
from customer_inventory_tbl c;
As a solution according to above mentioned description please try executing following sql query
SELECT *,(select count(id) from customer_inventory_tbl group by spex)
as count FROM customer_inventory_tbl WHERE name='John'
In above mentioned sql query counter value is being retrieved through subquery with records grouped according to values of spex column using GROUP BY clause.

Getting a SUM based off the column's relationship with another column (SQL)

So let's say you have the following data representing employees within a company. Column one is their unique ID, column 2 is the ID of their supervisor, and column 3 represents whether or not the employee is over 21. (Y means they are over 21, N means they are not)
|Employee ID |Supervisor ID|Over21|
-----------------------------------
|1 |1 |Y |
|2 |1 |N |
|3 |1 |Y |
|4 |2 |Y |
|5 |2 |Y |
|6 |3 |N |
|7 |3 |N |
So, if I wanted to find the number of employees that are over 21, I could do that pretty easily with:
SELECT SUM(CASE WHEN [Over21] IS 'Y' THEN 1 ELSE 0 END)
But let's say you want to find the number of supervisors that have an employee that is over 21. (In this example it would be 2). I've been racking my brain trying to figure out a way to write out a way to find that but I've been struggling so far.
select count (distinct Supervisor)
from your_tab
where Over21 = 'Y';
Without where:
select count (distinct case when Over21 = 'Y' then Supervisor else null end)
from your_tab;

Select with 5 tables creating almost duplicate rows

I have a database where I have to get name of the review where is the relevant comment and I also need to get the username of person who made that comment.
In order to do that, I have to go through 5 tables because there is no direct connection from comments tablejamacomments to review table review.
I can get review name by:
joining table revision_user with jamacomments
then joining revision_user table with user table userbase
then joining revision_user table with revision table revision which is just updated review
then joining revision table with review table review
My sql query:
select jamacomment.id, jamacomment.userId, jamacomment.commentText,
userbase.id, userbase.userName,
revision_user.userId, revision_user.revisionId,
revision.id, revision.reviewId, review.id, review.name
from jamacomment
left join revision_user
on jamacomment.userId=revision_user.userId
left join userbase
on revision_user.userId=userbase.id
left join revision
on revision_user.revisionId=revision.id
left join review
on revision.reviewId=review.id
group by jamacomment.id
To maybe clarify some things more clearly:
jamacomment.userId is foreign key userbase.id
revision_user.userId is foreign key to userbase.id ( so it's the same as jamacomment.userId)
revision_user.revisionId is foreign key to revision.id
revision.reviewId is foreign key to review.id
So I can get from jamacomment to revision_user from that to revision and from revision to review.
It leaves me with too many records, where it duplicates some data, but not fully. It is a duplicate to certain point where it gives random revisionId number and the rest of the data is wrong by that too.
By using group by I'm selecting only unique jamacomment.id because there can only be so many rows as there are comments. But It retrieves me with wrong records as I wanted to get. It shows some correct lines, but some with data wich is not that comment data, but different comment data.
Maybe I have incorrect select or some wrong left join or I should use other type of join, anyway, I could use any help, to get the correct data to each comment.
Adding dummy table with data for better understanding
table 'userbase' table 'jamacomment'
id | userName id | userId | commentText
1 | Peter 1 | 2 | First comment review1
2 | Jack 2 | 2 | Second comment review1
3 | Ann 3 | 1 | Comment in first review
4 | 1 | Comment in second review
5 | 1 | Comm in 2nd review 2nd revision
6 | 3 | Comment in review1 2nd revision
table 'revision_user' table 'revision' table 'review'
userId | revisionId id | reviewId | sequence id | name
2 | 1 1 | 1 | 1 1 | review1
2 | 1 2 | 2 | 1 2 | review2
1 | 1 3 | 1 | 2
1 | 2 4 | 2 | 2
1 | 4
3 | 3
Expected result should be:
table 'jamacomment' 'userbase' 'revision_user' 'revision' 'review'
id|userId |commentText |id |userName |userId |revisionId |id |reviewId |sequence|id|name
1 |2 |First comment review1 |2 |Jack |2 |1 |1 |1 |1 |1 |review1
2 |2 |Second comment review1 |2 |Jack |2 |1 |1 |1 |1 |1 |review1
3 |1 |Comment in first review |1 |Peter |1 |1 |1 |1 |1 |1 |review1
4 |1 |Comment in second review |1 |Peter |1 |2 |2 |2 |1 |2 |review2
5 |1 |Comm in 2nd review 2nd revision |1 |Peter |1 |4 |4 |2 |4 |2 |review2
6 |3 |Comment in review1 2nd revision |3 |Ann |3 |3 |3 |1 |2 |1 |review1
Forgot to add info that It supposedly breaks somewhere at revisionId where it makes duplicates of the data to revisionId but in revisionId changes the id to those lines. It adds 3 duplicates to each item. The rest info refers to the incorrect revisionId. I suppose It's 3 duplicates because I have 3 reviews or 3 revisions for one review.
It shows me 128 records without group by. with group by it shows the correct 36 records, but It gets some correct and some incorrect records.
Left join will populate your result try using inner join if you want to get only the matches record found on the table that you are joining.

How to find duplicate rows with similar part of string

I have thousands of rows in a table. Which is some rows has similar keyword but can be categorize to the same group. For example :
Table : Birds_Name
+-------+---------------------+
|ID |Name |
+-------+---------------------+
|1 |Blue Peckwood |
+-------+---------------------+
|2 |North Peckwood |
+-------+---------------------+
|3 |Northern Peckwood |
+-------+---------------------+
|4 |Northern Peckwood |
+-------+---------------------+
|5 |Red Heron |
+-------+---------------------+
|6 |Red Heron |
+-------+---------------------+
As for the table above there should be 2 groups of birds. They are Peckwook and Heron.
But after I run this mySQL I get :
SELECT *
FROM birds_name
WHERE name IN (
SELECT name
FROM birds_name
GROUP BY name
HAVING COUNT(*) > 1
)
After I run the query. This is what I've got:
+-------+---------------------+
|3 |Northern Peckwood |
+-------+---------------------+
|4 |Northern Peckwood |
+-------+---------------------+
|5 |Red Heron |
+-------+---------------------+
|6 |Red Heron |
+-------+---------------------+
Actually, I expect any row which share a similar string to be chosen (in this case it's Peckwood. So it should have only 2 groups - Peckwood and Heron.
Is it possible to do so? And how to adapt mysql code to achieve it?
Regards.
Try this
SELECT SUBSTRING_INDEX(name,' ',-1),count(*)
FROM birds_name
GROUP BY SUBSTRING_INDEX(name,' ',-1) HAVING count(*)>0;
Manual for SUBSTRING_INDEX function in mysql.
Can you try this.
SELECT count(id),name
FROM birds_name
group by name
having count(id) >1
Thanks
SQL Fiddle
I think you can separate those words using MySQL String functions, like below:
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
Then, use it in the GROUP BY clause of your query.
UPDATE :
Here is my SQLFiddle.

multicount on SQl query

I am looking for the proper SQl query to pull data from a the database and COUNT the specific rows to come up with a total... here's my table:
------------------------------------------
|name |App |Dep |Sold |
------------------------------------------
|Joe |1 |1 |2 |
|Joe |1 |2 |2 |
|Steve |1 |1 |1 |
|Steve |1 |2 |1 |
------------------------------------------
So I need to count the "1" in each column for each name and come up and output the totals like this:
Joe | 2 App | 1 Dep | 0 Sold
Steve | 2 App | 1 Dep | 2 Sold
Anyone have a starting point for me? I'm not sure if i need JOINs or i can just add seperate COUNTs for each column?
SELECT Name,
SUM(App = 1) TotalApp,
SUM(Dep = 1) TotalDep,
SUM(Sold = 1) TotalSold
FROM tableName
GROUP BY Name
SQLFiddle Demo
App = 1 is a mysql specific syntax which performs boolean arithmetic resulting 1 and 0. To make it more RDBMS friendly, you can use CASE eg. SUM(CASE WHEN App = 1 THEN 1 ELSE 0 END).
SQL Fiddle Demo using CASE statement