MYSQL Query Questions Search - mysql

Have been reading for a few days now and can't seem to get hold of my problem here.
Let me give you an insight of my DB:
table1 codes:
id CODE
1 D0G08H13L12
2 D1G12H10L12
3 D0G10H12L11
4 D1G10H10L09
5 D0G08H13L12
6 D1G12H10L12
7 D0G08H13L12
8 D1G10H10L09
9 D0G08H13L12
10 D1G12H10L12
now I'm searching for a query to count which codes occurs the most after D0G08H13L12, so searching in the next record my answer from the query would be:
3 times D1G12H10L12
1 time D1G10H10L09
this is what I have until now, I think I have to use subquery but I'm not quite sure.
SELECT id, code, COUNT(code) FROM table1 WHERE id IN ($idprint +1) GROUP BY code
ORDER BY COUNT(code) DESC
can any of you DB pro's help me in the good direction?

Try this:
SELECT COUNT(id) tot, `code`
FROM your_table
GROUP BY `code`
HAVING tot <=
(SELECT COUNT(id) FROM your_table
WHERE code = 'D0G08H13L12')
AND code <> 'D0G08H13L12'
ORDER BY tot DESC
If you want to have only two records append this to the query:
LIMIT 2

Try this, This will give u the desired result....
Select id, code, count(code)
from table1
where id>(select max(id) from table1 where code =D0G08H13L12) group by code order by count(code) desc;

select min(x.id), x.code
from yourTable x,
(
select * from yourTable
where code = 'D0G08H13L12'
) v
where
x.id > v.id
group by v.id
To get the most next codes for entered one.

Related

Stuck with Query Result

Would really appreciate it if someone could help me with my query.
Below is a sample table in which I want to retrieve those ActionId's which are not repeated twice or more.
I've tried not in, count, and distinct but no luck so far.
Required: Product=AA, OrderType=Market, ActionId=Non Repeated ones
select distinct ActionId,LocationId,PartyName from order where ActionIid in (select distinct ActionId from order where Product = 'AA'and OrderStatus = 'Complete') order by ActionId desc
select ActioId from order where Product ='AA'
and OrderType='Market'
and ActioId not in (
select ntd_id from order where Product ='AA'
and OrderType!='Limit'
and OrderType!='Stop'
group by ActioId having count(*)<2
)
group by ActionId
Where am I making the mistake?
Thanks in advance!
You want all the actionid appears once in the table for which product='AA' and ordertype='Market'. I have edited my answer. Please check:
select ActionId from order
group by actionid
having count(*)=1 and max(Product) ='AA' and max(OrderType)='Market'
I have no time to test this but this is how I would go fro this. It should only give you the ActioId that is only once in the table.
SELECT
`ActioId`
FROM `order `
WHERE
Product = 'AA'
AND
OrderType = 'Market'
GROUP BY
`ActioId`
HAVING
count(ActioId) < 2
ORDER BY
`ActioId` ASC

Fetch only 2 results, one for each different value of a concrete field

In a MYSQL table with those 5 fields: id, user_id, date, type, uid where type can be 1 or 2, I'm looking for a single query where I can fetch 2 results, one for type=1 and another one for type=2 based on date field.
Right now i have the following query which only gives me the last uid without taking care of the type field.
SELECT t.uid
FROM table AS t
WHERE t.user_id = 666
ORDER BY t.date
DESC LIMIT 1
Does anyone know how should modify this query so i can get the last uid for type=1 and the last one for type=2 based on date field? I would like to keep a a single query
Union all is probably the simplest method:
(select t.*
from t
where t.user_id = 666 and t.type = 1
order by date desc
limit 1
) union all
(select t.*
from t
where t.user_id = 666 and t.type = 2
order by date desc
limit 1
)
Finally i updated the query following this "paradigm":
http://dev.mysql.com/doc/refman/5.7/en/example-maximum-column-group-row.html
http://jan.kneschke.de/projects/mysql/groupwise-max/
This is how the query ended up:
SELECT s1.type, s1.uid
FROM t AS s1
LEFT JOIN t AS s2 ON s1.type = s2.type AND s1.date < s2.date
WHERE s2.date IS NULL;
Here's a visual example: http://hastebin.com/ibinidasuw.vhdl
Credits are for snoyes from #sql on Freenode. :)

Grouping users by group ids in mysql, exclude specified userid from the results?

There is a small application that I've been tasked on, that deals with getting latest posts in a group. In this sample below, I have there is a MySQL table formatted as such:
groupid userid date_updated
1 1 [date]
1 2 [date]
2 1 [date]
2 2 [date]
2 3 [date]
...
How do I do an SQL statement as such as the results go out in this manner (assuming I give a userid with a value of 1 for example):
groupid userid date
1 2 [date]
2 2 [date]
2 3 [date]
These are all ordered by date. As you may have noticed, the results do not include the provided userid (as the requirement is only to get users other than the supplied user ID). In other words, show only users other than the specified user in groups where the specified user is part of.
Is it possible to do this in a single SQL statement?
Search select query with where
select * from table where userid != '1'
Try the following solution.
select
tbl.*
from
tbl INNER JOIN
(select groupid, userid, max(date_updated)
from tbl
group by groupid, userid) tbl2
USING(groupid, userid)
ORDER BY tbl.date_updated;
You can use this
SELECT tbl.* FROM (SELECT * FROM tablename ORDER BY date DESC) as tbl GROUP BY tbl.groupid
I managed to find a possible answer to my question here with this SQL statement:
SELECT a.groupid, a.userid, a.date_updated
FROM group_participants a
WHERE a.groupid IN (
SELECT DISTINCT b.groupid FROM group_participants b WHERE b.userid = 1
)
AND a.user_id <> 1
GROUP BY a.userid
ORDER by a.date_updated DESC
Thank you guys those SQL statements you posted, gave me an idea. I don't know if the SQL statement above can still be optimized, but this one above gave me the correct answer.

Select sum of top three scores for each user

I am having trouble writing a query for the following problem. I have tried some existing queries but cannot get the results I need.
I have a results table like this:
userid score timestamp
1 50 5000
1 100 5000
1 400 5000
1 500 5000
2 100 5000
3 1000 4000
The expected output of the query is like this:
userid score
3 1000
1 1000
2 100
I want to select a top list where I have n best scores summed for each user and if there is a draw the user with the lowest timestamp is highest. I really tried to look at all old posts but could not find one that helped me.
Here is what I have tried:
SELECT sum(score) FROM (
SELECT score
FROM results
WHERE userid=1 ORDER BY score DESC LIMIT 3
) as subquery
This gives me the results for one user, but I would like to have one query that fetches all in order.
This is a pretty typical greatest-n-per-group problem. When I see those, I usually use a correlated subquery like this:
SELECT *
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3;
This is not the whole solution, as it only gives you the top three scores for each user in its own row. To get the total, you can use SUM() wrapped around that subquery like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId;
Here is an SQL Fiddle example.
EDIT
Regarding the ordering (which I forgot the first time through), you can just order by totalScore in descending order, and then by MIN(timestamp) in ascending order so that users with the lowest timestamp appears first in the list. Here is the updated query:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
and here is an updated Fiddle link.
EDIT 2
As JPW pointed out in the comments, this query will not work if the user has the same score for multiple questions. To settle this, you can add an additional condition inside the subquery to order the users three rows by timestamp as well, like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score
AND mT.timeCol <= m.timeCol) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
I am still working on a solution to find out how to handle the scenario where the userid, score, and timestamp are all the same. In that case, you will have to find another tiebreaker. Perhaps you have a primary key column, and you can choose to take a higher/lower primary key?
Query for selecting top three scores from table.
SELECT score FROM result
GROUP BY id
ORDER BY score DESC
LIMIT 3;
Can you please try this?
SELECT score FROM result GROUP BY id ORDER BY score DESC, timestamp ASC LIMIT 3;
if 2 users have same score then it will set order depends on time.
You can use a subquery
SELECT r.userid,
( SELECT sum(r2.score)
FROM results r2
WHERE r2.userid = r.userid
ORDER BY score DESC
LIMIT 3
) as sub
FROM result r
GROUP BY r.userid
ORDER BY sub desc
You should do it like this
SELECT SUM(score) as total, min(timestamp) as first, userid FROM scores
GROUP BY userid
ORDER BY total DESC, first ASC
This is way more efficient than sub queries. If you want to extract more fields than userid, then you need to add them to the group by.
This will of cause not limit the number of scores pr user, which indeed seems to require a subquery to solve.

Most Common Value SubQuery MySql

Is there any other way to write this query ?
I tried doing it in a subquery but it doesn't work because of the multiple columns. It seems like this query only works by itself. Please correct me
Records
PK recordId
dateViewed
CarViewed
I tried this
SELECT R.`dateViewed` FROM Records ,(
SELECT R.CarViewed, COUNT(R.CarViewed) as cnt FROM Records R
GROUP BY R.CarViewed
ORDER BY cnt DESC
LIMIT 1 ) AS favouriteCarOfTheDay
GROUP BY R.`dateViewed
Then I tried this
SELECT R.`dateViewed` ,COUNT(R.CarViewed) as cnt FROM Records ,
(
SELECT R.CarViewed FROM Records R
GROUP BY R.CarViewed
ORDER BY cnt DESC
LIMIT 1 ) AS favouriteCarOfTheDay
GROUP BY R.`dateViewed
Along many other queries I tried, I have no idea how to get it working.
In a nutshell for a specific date, I would like to get the most common cars that were viewed.
Like :
dateViewed favouriteCarOfTheDay
2012-09-22 | Nissan
2012-09-23 | BMW
try this
SELECT R.`dateViewed` ,COUNT(R.CarViewed) as cnt ,R.CarViewed FROM Records R
GROUP BY R.`dateViewed
ORDER BY COUNT(R.CarViewed) DESC
I think the following should work (disclaimer, not all my own work, adapted from an answer at another question)
SELECT DISTINCT
R.dateViewed,
R.CarViewed
FROM Records R
WHERE
R.dateViewed =
(SELECT R2.dateViewed FROM
(
SELECT R1.dateViewed, COUNT(*) AS numViewed
FROM Records R1
WHERE R1.CarViewed = R.CarViewed
GROUP BY R1.dateViewed
ORDER BY R1.numViewed DESC
) AS R2
LIMIT 1
)
ORDER BY r.dateViewed
Such things are really awful to do in MySQL so it might actually by slower than two correlated subquery but at least it returns both the car and it's viewcount:
SELECT counts.`dateViewed`,counts.`CarViewed` as favourite_car, counts.cnt
FROM
(SELECT R.`dateViewed` ,R.`CarViewed`, COUNT(*) as cnt
FROM Records
GROUP BY R.`dateViewed` ,R.`CarViewed`
) as counts JOIN
(SELECT R.`dateViewed`, MAX(cnt) as cnt
FROM
(SELECT R.`dateViewed` ,R.`CarViewed`, COUNT(*) as cnt
FROM Records
GROUP BY R.`dateViewed` ,R.`CarViewed`
) as q
GROUP BY R.`dateViewed`) as maxes
ON counts.cnt=maxes.cnt