MySql select from already selected data - mysql

Hello I am trying to select data from the already selected values.
Current query:
select t.ticket_num, t.item_id, t.trans_id
from tickets as t
inner join ticket_items as ti
on ti.id = t.item_id
where ti.online = 1
and ti.bundle = 5
and ti.type_id = 2
Data sample:
num | item | tran
5699 1328 766
5700 1328 766
5701 1328 766
5702 1328 766
5703 1328 766
5704 1330 767
5705 1330 767
5706 1330 767
5707 1330 767
5708 1330 767
5709 1332 768
5710 1332 768
5711 1332 768
5712 1332 768
5713 1332 768
5714 1333 768
5715 1333 768
5716 1333 768
5717 1333 768
5718 1333 768
5719 1334 768
5720 1334 768
5721 1334 768
5722 1334 768
5723 1334 768
5724 1336 769
5725 1336 769
5726 1336 769
5727 1336 769
5728 1336 769
5729 1338 770
5730 1338 770
5731 1338 770
5732 1338 770
5733 1338 770
5734 1339 770
5735 1339 770
5736 1339 770
5737 1339 770
5738 1339 770
5739 1340 770
5740 1340 770
5741 1340 770
5742 1340 770
From this data I want only the ones that have 15 or more items on tran, as you can see 766 has only 5 but 768 has 15 so I want everything from this data that has more than or equal to 15.
Thanks

Perform a subquery that looks up all groups of tran in your desired query that have 15 or more records (the key is using the GROUP BY and HAVING clauses). Then in your main query select all records where tran is found IN the subquery. So for instance:
select
t.ticket_num, t.item_id, t.trans_id
from tickets as t
inner join ticket_items as ti
on ti.id = t.item_id
where ti.online = 1
and ti.bundle = 5
and ti.type_id = 2
and trans_id in
(select t.trans_id
from tickets as t
inner join ticket_items as ti
on ti.id = t.item_id
where ti.online = 1
and ti.bundle = 5
and ti.type_id = 2
GROUP BY t.trans_id
HAVING count(t.trans_id)>=15
)
You could probably clean up the redundant JOIN by pulling it out into a Common Table Expression like so:
WITH tquery as (SELECT *
from tickets
inner join ticket_items as ti
on ti.id = t.item_id
where ti.online = 1
and ti.bundle = 5
and ti.type_id = 2
)
select
ticket_num, item_id, trans_id
from tquery
where trans_id in
(select t.trans_id
from tquery as t
GROUP BY t.trans_id
HAVING count(t.trans_id)>=15
)
More about the having clause in case you're wondering how it works: What's the difference between HAVING and WHERE?

Related

mysql - select MAX value by a group return wrong values of other column

I want to find MAX value by the code and my data like below:
id
date
code
price
74
2022-01-04
B
64
91
2022-01-07
A
174
112
2022-01-11
B
128
245
2022-01-12
C
841
550
2022-01-14
A
79
780
2022-01-20
B
55
821
2022-01-23
D
45
868
2022-01-28
C
50
890
2022-02-02
B
467
891
2022-02-03
D
58
892
2022-02-04
A
472
What I expect, it will return like below:
id
date
code
price
245
2022-01-12
C
841
890
2022-02-02
B
467
891
2022-02-03
D
58
892
2022-02-04
A
472
I'm using below query:
select x.id, x.date, x.code, y.yprice
from data AS x
inner join
(
select id, date, code, MAX(price) AS yprice
from data
group by code
) y
on x.id = y.id AND x.code = y.code
and give me below result:
About the result:
The value of MAX is right, however the id and date is wrong.
Any idea to fix the query?
Thank You...
SELECT X.ID,X.DATE,X.CODE,X.PRICE
FROM
(
SELECT C.id,C.date,C.code,C.price,
ROW_NUMBER()OVER(PARTITION BY C.code ORDER BY C.Price DESC)XCOL
FROM test AS C
)X WHERE X.XCOL=1
Could you please try this one

How to return the max row based on one column in join query? [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Get records with max value for each group of grouped SQL results
(19 answers)
Closed 4 years ago.
I have a query that returns a result set with some IDs from a few tables. If a get two or more rows with the same QuestionID I only want the one with MAX(QuestionSessionID). How can I achieve this?
I have tried a bunch of different variations with subqueries but with no success. How to achieve this?
The query:
SELECT AQS.QuestionSessionID, AQS.QuestionID, AQS.AnswerTextMarkerID, AQS.Correct, QG.ID AS QuestionGroupID
FROM AnswerQuestionSession AQS
JOIN QuestionSession QS ON QS.UserID = 3
JOIN Question Q ON AQS.QuestionID = Q.ID
JOIN QuestionGroup QG ON Q.QuestionGroupID = QG.ID
WHERE AQS.AnswerTextMarkerID IN (109,110,113,114,118,121,141,146,148,152,156,157,158,172,182,183,193,194,196,197,198,211,222,227,241,242,243,257,263,271,282,283,356,396,643,644,938,939,943,944,955,956,957,958,959,970,971,972,973,978,979,1110,1111,1112,1113,1114,1115,1116,1117,1118,1120,1121,1163,1164,1165,1166,1205,1240)
AND AQS.QuestionSessionID = QS.ID
ORDER BY AQS.QuestionID, AQS.QuestionSessionID DESC;
Current result set:
QuestionSessionID QuestionID AnswerTextMarkerID Correct QuestionGroupID
294441 112 121 1 25
22942 112 121 0 25
22942 126 141 1 39
131489 216 257 1 102
22942 222 263 1 106
22942 227 271 1 110
294435 760 955 1 5
294435 760 956 1 5
So, in the above example I only want one of the rows with QuestionID 112 (the one with MAX(QuestionSessionID) 294441), like this:
Desired result set:
QuestionSessionID QuestionID AnswerTextMarkerID Correct QuestionGroupID
294441 112 121 1 25
22942 126 141 1 39
131489 216 257 1 102
22942 222 263 1 106
22942 227 271 1 110
294435 760 955 1 5
294435 760 956 1 5
UPDATE:
Tried adding another join as suggested by a commenter, but didn't get it right. It seems to work only on rows with more than one of the same QuestionID:
SELECT AQS.QuestionSessionID, AQS.QuestionID, AQS.AnswerTextMarkerID, AQS.Correct, QG.ID AS QuestionGroupID, MaxId
FROM AnswerQuestionSession AQS
JOIN QuestionSession QS ON QS.UserID = 3
JOIN Question Q ON AQS.QuestionID = Q.ID
JOIN QuestionGroup QG ON Q.QuestionGroupID = QG.ID
JOIN (SELECT QuestionID, MAX(QuestionSessionID) as MaxId
FROM AnswerQuestionSession
GROUP BY QuestionID) as mq ON mq.QuestionID = AQS.QuestionID
WHERE AQS.AnswerTextMarkerID IN (109,110,113,114,118,121,141,146,148,152,156,157,158,172,182,183,193,194,196,197,198,211,222,227,241,242,243,257,263,271,282,283,356,396,643,644,938,939,943,944,955,956,957,958,959,970,971,972,973,978,979,1110,1111,1112,1113,1114,1115,1116,1117,1118,1120,1121,1163,1164,1165,1166,1205,1240)
AND AQS.QuestionSessionID = QS.ID
/*AND AQS.QuestionSessionID = MaxId*/
ORDER BY AQS.QuestionID, AQS.QuestionSessionID DESC;
QuestionSessionID QuestionID AnswerTextMarkerID Correct QuestionGroupID MaxId
294441 112 121 1 25 294441
22942 112 121 0 25 294441
22942 126 141 1 39 293891
131489 216 257 1 102 294071
22942 222 263 1 106 294013
22942 227 271 1 110 294013
294435 760 958 1 5 294435
294435 760 959 1 5 294435
294435 760 955 1 5 294435
294435 760 956 1 5 294435
294435 760 957 1 5 294435
294435 771 970 1 241 294435
294435 771 971 1 241 294435
294435 771 972 1 241 294435
294435 776 978 1 245 294435
131489 962 1205 1 318 293592
UPDATE 2:
I got it to work as expected with a small modification based on help from a commenter:
WORKING QUERY:
SELECT AQS.QuestionSessionID, AQS.QuestionID, AQS.AnswerTextMarkerID, AQS.Correct, QG.ID AS QuestionGroupID
FROM AnswerQuestionSession AQS
JOIN QuestionSession QS ON AQS.QuestionSessionID = QS.ID
JOIN Question Q ON AQS.QuestionID = Q.ID
JOIN QuestionGroup QG ON Q.QuestionGroupID = QG.ID
JOIN (SELECT QuestionID, MAX(QuestionSessionID) as MaxId
FROM AnswerQuestionSession AQS2
JOIN QuestionSession QS2 ON AQS2.QuestionSessionID = QS2.ID
WHERE QS2.UserID = 3
GROUP BY QuestionID) as mq ON mq.QuestionID = AQS.QuestionID
WHERE AQS.AnswerTextMarkerID IN (109,110,113,114,118,121,141,146,148,152,156,157,158,172,182,183,193,194,196,197,198,211,222,227,241,242,243,257,263,271,282,283,356,396,643,644,938,939,943,944,955,956,957,958,959,970,971,972,973,978,979,1110,1111,1112,1113,1114,1115,1116,1117,1118,1120,1121,1163,1164,1165,1166,1205,1240)
AND QS.UserID = 3
AND AQS.QuestionSessionID = MaxId;
Add a JOIN against a subquery on the AnswerQuestionSession table
JOIN (SELECT QuestionID, MAX(QuestionSessionID as MaxId)
FROM AnswerQuestionSession
GROUP BY QuestionID) as mq ON mq. QuestionID = Aqs. QuestionID
and then use it in the WHERE clause
AND Aqs.QuestionSessionID = MaxId
This is based on the updated question, I changed the join on QuestionSession and also made sure MaxId was used in the WHERE clause.
SELECT AQS.QuestionSessionID, AQS.QuestionID, AQS.AnswerTextMarkerID, AQS.Correct, QG.ID AS QuestionGroupID
FROM AnswerQuestionSession AQS
JOIN QuestionSession QS ON AQS.QuestionSessionID = QS.ID
JOIN Question Q ON AQS.QuestionID = Q.ID
JOIN QuestionGroup QG ON Q.QuestionGroupID = QG.ID
JOIN (SELECT QuestionID, MAX(QuestionSessionID) as MaxId
FROM AnswerQuestionSession
GROUP BY QuestionID) as mq ON mq.QuestionID = AQS.QuestionID
WHERE AQS.AnswerTextMarkerID IN (109,110,113,114,118,121,141,146,148,152,156,157,158,172,182,183,193,194,196,197,198,211,222,227,241,242,243,257,263,271,282,283,356,396,643,644,938,939,943,944,955,956,957,958,959,970,971,972,973,978,979,1110,1111,1112,1113,1114,1115,1116,1117,1118,1120,1121,1163,1164,1165,1166,1205,1240)
AND QS.UserID = 3
AND AQS.QuestionSessionID = MaxId
ORDER BY AQS.QuestionID, AQS.QuestionSessionID DESC;

MYSQL with SUM results and GROUP BY and SUM Again

I have a query that I need to SUM the trid column after summing the raised amount
SELECT
`ppm_campaign_id`.`meta_value` AS `campaign_id`,
`trasnlations`.`trid` AS `trid`,
`ppm_campaign_value`.`meta_value` AS `raised`
FROM (((`thf_posts` `posts`
LEFT JOIN `thf_postmeta` `ppm_campaign_id`
ON (((`ppm_campaign_id`.`meta_key` = 'campaign_id')
AND (`ppm_campaign_id`.`post_id` = `posts`.`ID`))))
LEFT JOIN `thf_postmeta` `ppm_campaign_value`
ON (((`ppm_campaign_value`.`meta_key` = 'campaign_value')
AND (`ppm_campaign_value`.`post_id` = `posts`.`ID`))))
LEFT JOIN `thf_icl_translations` `trasnlations`
ON ((`trasnlations`.`element_id` = `ppm_campaign_id`.`meta_value`)))
WHERE ((`ppm_campaign_id`.`meta_value` IS NOT NULL)
AND (`trasnlations`.`trid` IS NOT NULL))
GROUP BY `ppm_campaign_id`.`meta_value`
Result
campaign_id trid raised
1022 564 4137.5
1031 564 3937.5
1698 653 3010
1700 655 10
1702 657 750
1712 653 3030
1713 655 20
1727 657 20
2163 682 0.9
2164 682 50
2166 683 200
2168 684 50
Now I want the sum of trid combined so summing trid = 682 the result of raised should be 50.9 in both campaign_id
Expected Result
campaign_id trid raised
1022 564 8075
1031 564 8075
1698 653 3010
1700 655 10
1702 657 750
1712 653 3030
1713 655 20
1727 657 20
2163 682 50.9
2164 682 50.9
2166 683 200
2168 684 50
Considering the output of your query is stored in temptable. Please try the below query. Hope it helps.
SELECT t1.campaign_id, t1.trid, t2.raised_sum
FROM temptable t1 JOIN (
SELECT trid, SUM(raised) as raised_sum
FROM temptable GROUP BY trid) t2
ON t1.trid=t2.trid
GROUP BY t1.campaign_id, t1.trid, t2.raised_sum;
If more details on the tables included in your query and sample data can be given, we can try to get the data directly from them.

Join tables with different colums to single colum

First off, for categorization purposes, could someone figure out a better name to index this as?
Secondly, I have a table and I want to grab the username from another table to two columns on the same table.
SELECT ignite_board.*,username AS 'name'
FROM ignite_board,user_info
WHERE bnumber = 3
AND ignite_board.uid = user_info.id
ORDER BY POSITION
Gets me this:
ID bnumber position UID qual time following name
1176 3 1 442 2 1382045726 440 bb1
1177 3 2 445 2 1382045936 442 bb4
1181 3 3 450 2 1382050220 449 bb6
1178 3 4 446 2 1382050371 439 aa2
1209 3 5 466 1 1382050130 450 bb8
1212 3 6 469 2 1382050502 467 bb10
1210 3 7 467 1 1382050172 466 bb9
1232 3 8 475 1 1382050415 446 aa7
1180 3 9 444 0 1382045690 445 bb3
1214 3 10 471 0 1382050220 466 bb11
1233 3 11 476 0 1382050415 475 aa8
1179 3 12 441 0 1382045562 475 aa1
1182 3 13 452 0 1382046032 448 aa6
1216 3 14 473 0 1382050272 469 bb12
1234 3 15 477 0 1382050502 469 bb16
1271 3 16 454 0 1382306814 442 bb7
But what would I need to get the username and the Following username (sorta like this)
SELECT ignite_board.*,username AS 'name',username AS 'following'
FROM ignite_board,user_info
WHERE bnumber = 3
AND ignite_board.uid = user_info.id
AND ignite_board.following = user_info.id
ORDER BY POSITION
SELECT b.*
, u.username name
, f.username following
FROM ignite_board b
JOIN user_info u
ON u.id = b.uid
JOIN user_info f
ON f.id = b.following
WHERE bnumber = 3
ORDER
BY position;
You have to join the user_info table twice, and give a different alias to each instance:
SELECT ignite_board.*,u.username AS 'name',f.username AS 'following'
FROM ignite_board,user_info u, user_info f
WHERE bnumber = 3
AND ignite_board.uid = u.id
AND ignite_board.following = f.id
ORDER BY POSITION

SELECT MIN, MAX, AVG and current (for latest insert ID) value all together

I need to get GROUPed BY values,
but I need to see not a random price value (when I select price), but latest price value (price for a row with highest ID within this GROUP)
SELECT ID, price,
ROUND(AVG(price)),
MIN(price),
MAX(price),
ROUND((AVG(price)-MIN(price))/AVG(price) * 100) as differenceinprices
FROM `m-orbitzone`
WHERE dep = 'MOW'
AND returnornot = 1
GROUP BY arv, date1, date2
ORDER BY differenceinprices DESC LIMIT 1000
ID price <-- ROUND(AVG(price)) MIN(price) MAX(price) differenceinprices
122841 834 816 534 834 35
122708 783 790 524 821 34
122754 766 796 529 815 34
28528 810 766 512 810 33
28529 799 765 512 799 33
122603 766 798 534 841 33
122848 766 794 529 810 33
122589 778 765 519 778 32
122591 778 768 519 778 32
122749 766 775 529 814 32
28527 752 749 512 773 32
122744 766 773 529 814 32
122843 766 771 529 802 31
Need 'price' to be latest price for this GROUP (row with highest ID)
May be need to do SELECT and then to do one more SELECT from result?
Thank you!
This should do the trick:
SELECT m.ID, price,
ROUND(AVG(price)),
MIN(price),
MAX(price),
ROUND((AVG(price)-MIN(price))/AVG(price) * 100) as differenceinprices
FROM `m-orbitzone` m
INNER JOIN (
SELECT
ID
FROM
`m-orbitzone` m
WHERE ID = (SELECT MAX(ID) FROM `m-orbitzone` sm WHERE m.arv = sm.arv AND m.date1 = sm.date1 AND m.date2 = sm.date2)
) s ON m.ID = s.ID
WHERE dep = 'MOW'
AND returnornot = 1
GROUP BY arv, date1, date2
ORDER BY differenceinprices DESC LIMIT 1000
A good read about the topic is this manual entry.