Get the latest 3 nodes foreach taxonomy term in one query - mysql

I am trying to setup a query to get the 3 most recent nodes (nid) foreach taxonomy term (tid). Is this possible to set up on one query?
Here are how my tables are set up (not displaying full table info)
taxonomy_index (Holds the taxonomy ids that are associated to a node)
nid tid
1 20
1 21
1 22
2 20
2 21
3 23
3 24
4 20
4 21
5 20
5 21
5 22
5 23
6 20
6 21
6 24
7 20
7 21
8 20
8 21
9 20
9 21
9 22
9 23
.....
node (node information)
nid title created
1 Article One 1105350260
2 Article Two 1105350259
3 Article Three 1105350261
4 Article Four 1105350280
5 Article Five 1105350290
6 Article Six 1105350290
.....
I'm envisioning a result like this if I wanted to see the latest 3 nodes for tids: 20, 21, 22:
tid nid
20 1
20 2
20 4
21 1
21 2
21 4
22 1
22 5
22 9
Is this possible in one query?

You can try follwing query:-
SELECT t.tid, t.nid
FROM taxonomy_index s
WHERE (SELECT COUNT(*)
FROM taxonomy_index f
WHERE f.tid = s.tid
AND f.nid <= s.nid
) <= 3;
here i have used <=3 #cond, in case if any tid dont have 3 records the it will fetch 2 or 1, whichever is more.

Related

Selecting or Updating with 2 group criteria for a max value on mysql [duplicate]

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 3 years ago.
I'm trying to figure out how to use group and max() on joins correctly, I'm doing some parsing of a moodle(Open source school software) mysql database. Students are allowed to retake the quizes indefinatly for this particular program, but I need to be able to update the course completion date to reflect the last time they took the test because a lot of other things depend on the completion fields.
The mdl_quiz_attempts table stores all attempts for all quizes, the userid will have many of the same entries, but the attempt number is not unique to the table, but instead unique to both the student AND the key for the row. Meaning students have multiple entries. On the mdl_course_modules table, The instance field is the key for the mdl_quiz table, and the mdl_course_modules_completion coursemoduleid field is the key for mdl_course_modules.
So what I want to do is this:
given a student id
UPDATE mdl_course_completion.timemodified to mdl_quize_attempts.timemodified
WHERE the row on mdl_quiz_attempts is the max attempt by userid for each quiz.(the quiz field on the quiz_attempts has to be looked up through in course module instance table to get the, instance id for course completion module id)
Here are example partial tables.
mdl_quiz_attempts
id quiz userid attempt timemodified
2 1 3 6 1365408901
6 1 4 1 1369873688
7 2 4 1 1369877532
8 7 4 1 1369881431
9 7 4 2 1369882897
12 5 4 1 1505165504
13 6 4 1 1369887643
17 8 4 1 1369958105
18 1 4 2 1374557701
22 7 4 3 1374639901
23 6 4 7 1374640202
24 5 4 2 1374639901
25 8 4 2 1374639901
26 2 4 2 1374639301
27 2 6 1 1376620469
29 2 12 1 1389915486
30 1 23 1 1390978667
31 1 23 2 1391030924
32 2 23 1 1392113103
33 2 23 2 1392696602
34 2 23 3 1392767435
35 7 12 1 1398914256
36 8 43 1 1405281193
37 1 50 1 1405522411
38 5 43 1 1505165504
mdl_course_modules
id course module instance section
3 2 9 2 3
5 2 17 2 4
7 2 17 3 5
8 2 17 4 6
9 2 17 5 7
10 2 17 6 8
11 2 17 7 9
12 2 17 8 10
13 2 17 9 11
14 2 17 10 12
15 2 17 11 13
25 2 16 1 14
26 2 23 1 4
28 2 7 1 14
30 4 9 4 26
42 4 23 3 33
45 4 23 6 38
46 4 23 7 37
47 4 23 8 36
48 4 23 9 35
49 4 23 10 32
50 4 23 11 34
51 5 9 5 27
53 5 23 12 43
55 5 23 13 44
mdl_quiz
id name
10 Unit 10 Quiz
11 Unit 2 Quiz
12 Unit 3 Quiz
13 Unit 5 Quiz
14 Unit 1 Quiz
15 Unit 8 Quiz
16 Unit 9 Quiz
17 Unit 7 Quiz
18 Unit 4 Quiz
mdl_course_modules_completion
id coursemoduleid userid completionstate viewed timemodified
14 25 2 0 1 0
15 25 6 0 1 0
67 25 4 1 1 1369873688
68 28 4 1 0 1369874483
69 192 4 1 0 1369875233
70 184 4 1 1 1369877532
Something like this ?
update mdl_course_modules_completion c
join mdl_quiz_attempts a on a.userid = c.userid
join (select max(attempt) max_attempts from mdl_quiz_attempts group by userid) max on max.max_attempts = a.attempt
set c.timemodified = a.timemodified
where c.userid = :<USER_ID>

MYSQL I am trying to return a value where I need to compare one value against the minimum value for the same field when grouped against another field

Basically I am trying to calculate shots received in golf for various four balls, here is my data:-
DatePlayed PlayerID HCap Groups Hole01 Hole02 Hole03 Shots
----------------------------------------------------------------------
2018-11-10 001 15 2 7 3 6
2018-11-10 004 20 1 7 4 6
2018-11-10 025 20 2 7 4 5
2018-11-10 047 17 1 8 3 6
2018-11-10 048 20 2 8 4 6
2018-11-10 056 17 1 6 3 5
2018-11-10 087 18 1 7 3 5
I want to retrieve the above lines with an additional column which is to be calculated depending on the value in the group column, which is the players (Handicap - (the lowest handicap in the group)) x .75
I can achieve it in a group by but need to aggregate everything, is there a way I can return the value as above?, here is query that returns the value:
SELECT
PlayerID,
MIN(Handicap),
MIN(Hole01) AS Hole01,
MIN(Hole02) AS Hole02,
MIN(Hole03) AS Hole03,
MIN(CourseID) AS CourseID,
Groups,
ROUND(
MIN((Handicap -
(SELECT MIN(Handicap) FROM Results AS t
WHERE DatePlayed='2018-11-10 00:00:00' AND t.Groups=Results.Groups)) *.75))
AS Shots
FROM
Results
WHERE
Results.DatePlayed='2018=11=10 00:00:00'
GROUP BY
DatePlayed, Groups, PlayerID
.
PlayerID MIN(Handicap)Hole01 Hole02 Hole03 CourseID Groups Shots
-----------------------------------------------------------------
4 20 7 4 6 1 1 2
47 17 8 3 6 1 1 0
56 17 6 3 5 1 1 0
87 18 7 3 5 1 1 1
1 15 7 3 6 1 2 0
25 20 7 4 5 1 2 4
48 20 8 4 6 1 2 4
Sorry about any formatting really couldn't see how to get my table in here, any help will be much appreciated, I am using the latest mysql from ubuntu 18.04
Not an answer; too long for a comment...
First off, I happily know nothing about golf, so what follows might not be optimal, but it must, at least, be a step in the right direction...
A normalized schema might look something like this...
rounds
round_id DatePlayed PlayerID HCap Groups
1 2018-11-10 1 15 2
2 2018-11-10 4 20 1
round_detail
round_id hole shots
1 1 7
1 2 3
1 3 6
2 1 7
2 2 4
2 3 6
Hi Guys I have found the solution, basically I need to drop the MIN immediately after the ROUND of the equation and therefore it does not need a Group By.
SELECT
PlayerID,
Handicap,
Hole01,
Hole02,
Hole03,
CourseID,
Groups,
ROUND((Handicap -
(SELECT MIN(Handicap) FROM Results AS t
WHERE DatePlayed='2018-11-10 00:00:00'
AND t.Groups=Results.Groups))
*.75) AS Shots
FROM
Results
WHERE
Results.DatePlayed='2018=11=10 00:00:00'

How to select 3 row per category in MySQL?

I have a table which have a lot of data, it's have a category ID and postId, I need to read 3 new post per category with same CatID.
it's not duplicate of the question suggest by other people. Please check that in my question the postid catid can be anything when in duplicate question it's calculate before running query.
What I have written is
SELECT
MAX(` postid `) AS p1,
` catid ` AS c1
FROM
` postcategory `
GROUP BY
` catid
I can put 2 other query in it union distinct but it will make a query a lot big. Is there any good way to do this in MySQL. What I am looking for reading 3 postId (maximum) belong to same category.
postId catId
------ --------
9 3
15 3
16 3
17 3
18 3
19 5
20 8
21 6
22 8
23 6
46 6
46 8
26 3
25 3
27 5
28 3
37 6
39 10
40 6
41 6
42 6
43 6
44 5
45 11
63 6
64 5
65 6
66 6
68 6
You can read 3 new post from each category Using the below query.
SELECT
p1.postId,
p1.catId
FROM
postcategory p1
JOIN postcategory p2 ON p1.catId = p2.catId
AND p2.postId >= p1.postId
GROUP BY
p1.postId,
p1.catId
HAVING
COUNT(*) <= 3
ORDER BY
catId,
postId
Here you can see the Live Demo
Output:

count items in col as rows MYSQL

Dear developers and programmers,
I have a tabel with SHOP_ID, PROD_ID, ipadres and some more tables, but these are where its all about...
Looks like this:
id ip number timestamp shop_id prod_id
--------------------------------------------------
42 81.69.205.25 1319488326 2 3
43 81.205.141.48 1319492649 2 3
44 193.58.10.10 1319520579 14 17
45 84.28.22.226 1319529529 11 19
46 88.15.81.188 1319543745 2 1
47 178.17.241.191 1319563031 14 7
48 87.28.107.171 1319563038 2 6
49 80.156.47.144 1319572818 14 7
50 82.76.241.175 1319577506 11 1
51 82.76.241.175 1319577584 13 1
52 82.76.241.175 1319577785 14 1
53 82.76.241.175 1319577860 4 1
54 62.94.133.153 1319579221 14 1
55 62.94.133.153 1319579281 2 3
56 77.70.175.221 1319617238 11 1
57 77.70.175.221 1319621845 13 1
58 77.70.175.221 1319621848 2 1
59 77.70.175.221 1319621850 11 1
.... more
--------------------------------------------------------
Is there a way to see for each prod_id how many ip numbers there excist for each shop id?
output example
1 2 3 4 5
---------------------------------------------
1 18 5 51 8 4
2 58 5 45 3 4
3 7 6 31 9 2
where horizontal is the prod_id and vertical is the shop_id
I've don this already:
select
shop_id,
count(distinct(ipadres)) amount
from table
GROUP BY shop_id
order by amount desc
but this wil give me only the result of all prod_id's combined.
I would like to have the prod_id's seperate in columns.
I hope there is a solution!
Kind Regards
Try this
select `prod_id`,shop_id,
count(distinct(ipadres)) amount
from table
GROUP BY shop_id,prod_id
order by amount desc

Any Advice with Mysql Count

i have a t_class table in mySql,
in this table there are 3 columns, No, CLASS and POINT.
and there are approximately 5000 records in this table. i want the count of classes in this table.
No CLASS POINT
1 9 100
2 10 70
3 11 80
4 9 90
5 10 50
6 M 60
7 M 70
8 9 40
9 10 90
10 11 90
11 M 80
12 M 75
13 11 40
14 10 100
15 9 60
As you see there 4 types of classes - 9, 10, 11 and M.
But there is one problem. When it calculates the count of classes it must
summarize 11-th and M th classes. For example
CLASS COUNT
9 4
10 4
11 7
Thanks.
SELECT CLASS, COUNT(*) AS CNT
FROM table
GROUP BY CASE WHEN CLASS='M' THEN '11' ELSE CLASS END