How do I get a DISTINCT in this query - mysql

this is my query:
SELECT phpbb_attachments.attach_id, phpbb_attachments.post_msg_id
FROM phpbb_attachments
INNER JOIN phpbb_topics
ON phpbb_attachments.topic_id = phpbb_topics.topic_id
INNER JOIN phpbb_forums ON phpbb_topics.forum_id = phpbb_forums.forum_id
WHERE phpbb_attachments.is_orphan = 0
AND phpbb_attachments.thumbnail = 1
AND (phpbb_attachments.extension = 'jpg'
OR phpbb_attachments.extension = 'png'
OR phpbb_attachments.extension = 'gif')
AND phpbb_forums.forum_id BETWEEN 668 AND 679
ORDER BY phpbb_attachments.attach_id DESC
LIMIT 50
I want to get only the latest 1 attachment per topic.
So sort of like a distinct on phpbb_attachments.topic_id

This query gives the "best" attachment per ropic:
SELECT MAX(a.attach_id), t.topic_id
FROM phpbb_attachments a
INNER JOIN phpbb_topics t ON a.topic_id = t.topic_id
INNER JOIN phpbb_forums f ON t.forum_id = f.forum_id
WHERE a.is_orphan = 0
AND a.thumbnail = 1
AND (a.extension = 'jpg' OR a.extension = 'png' OR a.extension = 'gif')
AND f.forum_id BETWEEN 668 AND 679
GROUP BY t.topic_id
Then select attachments from that list:
SELECT x.attach_id, x.post_msg_id
FROM phpbb_attachments x INNER JOIN (SELECT MAX(a.attach_id) AS attach_id, t.topic_id
FROM phpbb_attachments a
INNER JOIN phpbb_topics t ON a.topic_id = t.topic_id
INNER JOIN phpbb_forums f ON t.forum_id = f.forum_id
WHERE a.is_orphan = 0
AND a.thumbnail = 1
AND (a.extension = 'jpg' OR a.extension = 'png' OR a.extension = 'gif')
AND f.forum_id BETWEEN 668 AND 679
GROUP BY t.topic_id) i ON x.attach_id = i.attach_id
ORDER BY x.attach_id DESC
LIMIT 50

The id of SELECT phpbb_attachments.attach_id, phpbb_attachments.post_msg_id is not the same.
Now when you execute that Script even using SELECT distinct phpbb_attachments.attach_id, phpbb_attachments.post_msg_id, it will not generate a distinctphpbb_attachments.attach_id`.
The Reason is:
It will creating two distinct with this fields phpbb_attachments.attach_id, phpbb_attachments.post_msg_id
Now if you need a Distinct to this phpbb_attachments.attach_id
You have to do it first distinct:
SELECT Distinct phpbb_attachments.attach_id
FROM phpbb_attachments
INNER JOIN phpbb_topics
ON phpbb_attachments.topic_id = phpbb_topics.topic_id
INNER JOIN phpbb_forums ON phpbb_topics.forum_id = phpbb_forums.forum_id
WHERE phpbb_attachments.is_orphan = 0
AND phpbb_attachments.thumbnail = 1
AND (phpbb_attachments.extension = 'jpg'
OR phpbb_attachments.extension = 'png'
OR phpbb_attachments.extension = 'gif')
AND phpbb_forums.forum_id BETWEEN 668 AND 679
ORDER BY phpbb_attachments.attach_id DESC
LIMIT 50
then use left join to that particular Distinct Data using phpbb_attachments.attach_id itself something like:
SELECT attach_id,post_msg_id
FROM
(SELECT Distinct phpbb_attachments.attach_id,
FROM phpbb_attachments
INNER JOIN phpbb_topics
ON phpbb_attachments.topic_id = phpbb_topics.topic_id
INNER JOIN phpbb_forums ON phpbb_topics.forum_id = phpbb_forums.forum_id
WHERE phpbb_attachments.is_orphan = 0
AND phpbb_attachments.thumbnail = 1
AND (phpbb_attachments.extension = 'jpg'
OR phpbb_attachments.extension = 'png'
OR phpbb_attachments.extension = 'gif')
AND phpbb_forums.forum_id BETWEEN 668 AND 679
ORDER BY phpbb_attachments.attach_id DESC
LIMIT 50) as firstDistinct
LEFT JOIN
(SELECT phpbb_attachments.attach_id, phpbb_attachments.post_msg_id
FROM phpbb_attachments
INNER JOIN phpbb_topics
ON phpbb_attachments.topic_id = phpbb_topics.topic_id
INNER JOIN phpbb_forums ON phpbb_topics.forum_id = phpbb_forums.forum_id
WHERE phpbb_attachments.is_orphan = 0
AND phpbb_attachments.thumbnail = 1
AND (phpbb_attachments.extension = 'jpg'
OR phpbb_attachments.extension = 'png'
OR phpbb_attachments.extension = 'gif')
AND phpbb_forums.forum_id BETWEEN 668 AND 679
ORDER BY phpbb_attachments.attach_id DESC
LIMIT 50) as secondNotDistinct
On firstDistinct.attach_id = secondNotDistinct.attach_id

Related

A query is taking 9 hours to import 1.900.000 rows from Database A to Amazon Quicksight

Log History:
2020/04/13 22:12:36 Completed
Ingestion completed in 9 hours 22 minutes 1 seconds.
Rows dropped: 0, Rows ingested: 1916870
Manual, Full refresh
SELECT
uc.name,
u.username AS usuario,
u.firstname,
u.lastname,
c.fullname AS titulo_bit,
CASE
WHEN EXISTS(SELECT ci.id
FROM mdl_certificate_issues ci
LEFT JOIN mdl_certificate ce ON (ci.certificateid = ce.id)
WHERE ci.userid = u.id
AND ce.course = c.id)
THEN 100
ELSE
ROUND(COUNT(cmc.completionstate) * 100 / (SELECT COUNT(*)
FROM mdl_course_modules
WHERE course = cm.course
AND deletioninprogress IS false
AND completion IS true))
END AS porcentaje_avance_bit,
uai.company_area AS area_old,
u.department,
u.address,
u.institution,
muca.name AS area,
FROM_UNIXTIME(cmc.timemodified) as course_progress_time
FROM mdl_course_modules_completion cmc
LEFT JOIN mdl_course_modules cm ON (cmc.coursemoduleid = cm.id)
LEFT JOIN mdl_course c ON (cm.course = c.id)
LEFT JOIN mdl_user u ON (cmc.userid = u.id)
LEFT JOIN mdl_u_user_additional_info uai ON (u.id = uai.mdl_user_id)
LEFT JOIN mdl_u_company_area muca ON uai.company_area_id = muca.id
RIGHT JOIN mdl_u_company uc ON (uai.mdl_u_company_id = uc.id)
WHERE cm.deletioninprogress IS false
AND cm.completion IS true
AND cmc.completionstate != 0
AND u.deleted IS FALSE
AND c.visible IS TRUE
GROUP BY cm.course, cmc.userid, uc.name, uai.company_area, muca.id, FROM_UNIXTIME(cmc.timemodified)
ORDER BY usuario, course_progress_time desc

how to simplify the selection query

I have to selection queries like below in a stored procedure.
SELECT #licenseCount = COUNT(*) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId = SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate)) > 0
SELECT #paymentCount = COUNT(*) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId=SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate)) > 0
AND UP.PaymentStatus = 'P'
As you can see, the only difference between the above two selection queries is that, at the end of second one, there is an extra where condition, AND UP.PaymentStatus = 'P'.
So I was wondering is there any way I can simplify this queries?
Below would be the query
SELECT #licenseCount = COUNT(*), #paymentCount = COUNT(case when UP.PaymentStatus = 'P' then 1 else 0 end) FROM ServicePool SP
INNER JOIN UserPackages UP ON UP.ServicePoolId = SP.Id
AND SP.UserId = UP.UserId
INNER JOIN Package P ON P.Id = UP.PackageId
LEFT OUTER JOIN CompanyProfile C ON C.LicenseId = SP.Id
INNER JOIN CompanyProfile CP ON CP.CurrencyId = P.CurrencyId
INNER JOIN PackageCategory PC ON PC.OrganizationTypeId = CP.OrganisationType
AND PC.PackageId = P.Id
WHERE SP.Active = 1
AND SP.UserId = #uId
AND P.Active = 1
and CP.CompanyID = #cId
and ISNULL(C.CompanyID,0) = 0
AND
DATEDIFF(DAY,GETDATE(),DATEADD(DAY,P.ValidityPeriod,UP.PurchaseDate))
You can define #paymentCount variable in the first query itself
Test Results -
hive> select * from test_so_t1;
OK
123 90001 90001
123 90001 90002
123 90001 90003
123 90002 90001
123 90002 90002
123 90003 90002
123 90003 90003
Time taken: 0.118 seconds, Fetched: 7 row(s)
hive> select count(case when mem_id=90001 then 1 else 0 end) as groupBy, group_id from test_so_t1 group by group_id;
Total MapReduce CPU Time Spent: 3 seconds 900 msec
OK
7 123
Time taken: 17.271 seconds, Fetched: 1 row(s)

Show rows with SUM of two columns with subqueries and multiple JOINS

Hello I'm about to explode.. I have been trying for hours now getting this to work. I have found different solutions for others and tried to rewrite it so it fits to my script but it just wont work as it should.
With reference from Barmar to this post: Join tables with SUM issue in MYSQL
I have got a little way forward but I can't get it to print out what it should.
I have tried a lot of variant and moved around the JOINS etc. but without any luck. This is the query that gets nearest my wanted result:
SELECT
qs.statistic_ref_id,
qs.question_id,
SUM(qs.correct_count) AS count_correct,
qs2.total_count_2 AS total_count,
sr.user_id,
sr.quiz_id,
qq.title AS ny_titel,
qq.category_id,
SUBSTRING(qq.title,1,4) AS get_type_number,
pl.points
FROM pro_quiz_statistic AS qs
JOIN pro_quiz_statistic_ref sr ON sr.statistic_ref_id = qs.statistic_ref_id
JOIN pro_quiz_question qq ON qq.id = qs.question_id
JOIN user_points_log pl ON pl.quiz_id = sr.quiz_id AND pl.user_id = '$user_id'
JOIN ( SELECT
qs3.statistic_ref_id,
qs3.question_id,
SUM(qs3.correct_count + qs3.incorrect_count) AS total_count_2,
sr3.user_id,
sr3.quiz_id,
qq3.title AS ny_titel_2,
qq3.category_id,
SUBSTRING(qq3.title,1,4) AS get_type_number_2,
pl3.points
FROM pro_quiz_statistic AS qs3
JOIN pro_quiz_statistic_ref sr3 ON sr3.statistic_ref_id = qs3.statistic_ref_id
JOIN pro_quiz_question qq3 ON qq3.id = qs3.question_id
JOIN user_points_log pl3 ON pl3.quiz_id = sr3.quiz_id AND pl3.user_id = '$user_id'
WHERE sr3.user_id = '$user_id' AND
qq3.category_id = '3'
GROUP BY get_type_number_2 ORDER BY qs3.question_id
) qs2 ON qs2.statistic_ref_id = sr.statistic_ref_id
WHERE sr.user_id = '$user_id' AND
qq.category_id = '3'
GROUP BY get_type_number ORDER BY qs.question_id
You can see the outcome of this result in this picture (to the right):
whats_printing.jpg
The two first tables is pictures of the queries separately and is what it should print out. Just in one query.
I have tried with these two subqueries:
SELECT
qs.statistic_ref_id,
qs.question_id,
qs2.correct_count AS count_correct,
qs3.total_count_2 AS total_count,
sr.user_id,
sr.quiz_id,
qq.category_id,
SUBSTRING(qq.title,1,4) AS get_type_number,
pl.points
FROM pro_quiz_statistic AS qs
JOIN pro_quiz_statistic_ref sr ON sr.statistic_ref_id = qs.statistic_ref_id
JOIN pro_quiz_question qq ON qq.id = qs.question_id
JOIN user_points_log pl ON pl.quiz_id = sr.quiz_id AND pl.user_id = '$user_id'
JOIN (
SELECT
qs2.statistic_ref_id,
qs2.question_id,
SUM(qs2.correct_count) AS count_correct_2,
sr2.user_id,
sr2.quiz_id,
qq2.category_id,
SUBSTRING(qq2.title,1,4) AS get_type_number_2,
pl2.points
FROM pro_quiz_statistic AS qs2
JOIN pro_quiz_statistic_ref sr2 ON sr2.statistic_ref_id = qs2.statistic_ref_id
JOIN pro_quiz_question qq2 ON qq2.id = qs2.question_id
JOIN user_points_log pl2 ON pl2.quiz_id = sr2.quiz_id AND pl2.user_id = '$user_id'
WHERE sr2.user_id = '$user_id' AND
qq2.category_id = '3'
GROUP BY get_type_number_2
ORDER BY qs2.question_id
) qs2 ON qs2.statistic_ref_id = qs.statistic_ref_id
JOIN ( SELECT
qs3.statistic_ref_id,
qs3.question_id,
SUM(qs3.correct_count + qs3.incorrect_count) AS total_count_2,
sr3.user_id,
sr3.quiz_id,
qq3.category_id,
SUBSTRING(qq3.title,1,4) AS get_type_number_3,
pl3.points
FROM pro_quiz_statistic AS qs3
JOIN pro_quiz_statistic_ref sr3 ON sr3.statistic_ref_id = qs3.statistic_ref_id
JOIN pro_quiz_question qq3 ON qq3.id = qs3.question_id
JOIN user_points_log pl3 ON pl3.quiz_id = sr3.quiz_id AND pl3.user_id = '$user_id'
WHERE sr3.user_id = '$user_id' AND
qq3.category_id = '3'
GROUP BY get_type_number_3
ORDER BY qs3.question_id
) qs3 ON qs3.statistic_ref_id = qs.statistic_ref_id
WHERE sr.user_id = '$user_id' AND
qq.category_id = '3'
GROUP BY get_type_number
ORDER BY qs.question_id
but then it's not printing anything. This works:
SELECT
qs.statistic_ref_id,
qs.question_id,
SUM(qs.correct_count) AS count_correct,
sr.user_id,
sr.quiz_id,
qq.title AS ny_titel,
qq.category_id,
SUBSTRING(qq.title,1,4) AS get_type_number,
pl.points
FROM pro_quiz_statistic AS qs
JOIN pro_quiz_statistic_ref sr ON sr.statistic_ref_id = qs.statistic_ref_id
JOIN pro_quiz_question qq ON qq.id = qs.question_id
JOIN user_points_log pl ON pl.quiz_id = sr.quiz_id AND pl.user_id = '$user_id'
WHERE sr.user_id = '$user_id' AND
qq.category_id = '3'
GROUP BY get_type_number ORDER BY qs.question_id
And also this (if I run them separately):
SELECT
qs.statistic_ref_id,
qs.question_id,
SUM(qs.correct_count + qs.incorrect_count) AS count_correct,
sr.user_id,
sr.quiz_id,
qq.title AS ny_titel,
qq.category_id,
SUBSTRING(qq.title,1,4) AS get_type_number,
pl.points
FROM pro_quiz_statistic AS qs
JOIN pro_quiz_statistic_ref sr ON sr.statistic_ref_id = qs.statistic_ref_id
JOIN pro_quiz_question qq ON qq.id = qs.question_id
JOIN user_points_log pl ON pl.quiz_id = sr.quiz_id AND pl.user_id = '$user_id'
WHERE sr.user_id = '$user_id' AND
qq.category_id = '3'
GROUP BY get_type_number ORDER BY qs.question_id
But how can I combine those two to one query?

mysql query hotel availability (Not calculate the total price)

Search the list of accommodation and the total price..
Here is my query and output: http://sqlfiddle.com/#!2/eaf58/43
query:
SELECT count(candidates.accommodation_id) as total, candidates.accommodation_id, omc_accommodation_season_period.season_id,
room_1, r1_price.price_normal AS room_1_price,
(SELECT SUM(room1_price.price_normal)
FROM omc_accommodation_room_pricelist room1_price
INNER JOIN omc_accommodation_room room1
ON room1_price.accommodation_id = room1.accommodation_id
INNER JOIN omc_accommodation_season_period so1
ON room1_price.accommodation_id = so1.accommodation_id
AND room1_price.season_id = so1.season_id
INNER JOIN omc_accommodation accommodation1
ON room1_price.accommodation_id = accommodation1.id
WHERE
so1.date BETWEEN '2013-08-13' AND '2013-08-15' AND
room1.quantity >= 3 AND room1.pax_max = 1 AND
accommodation1.id = candidates.accommodation_id AND
room1.id = room_1) AS room_1_sum,
room_2,r2_price.price_normal AS room_2_price,
omc_accommodation_season_period.date
FROM (SELECT r1.accommodation_id, r1.id AS room_1,
r2.id AS room_2, r1.quantity AS room_1_quantity,
r2.quantity AS room_2_quantity
FROM
omc_accommodation_room r1
INNER JOIN
omc_accommodation_room r2 ON r1.accommodation_id = r2.accommodation_id
WHERE
r1.quantity >= 3 AND r2.quantity >= 4 AND r1.pax_max = 1 AND r2.pax_max = 2) AS candidates
LEFT JOIN omc_accommodation_season_period
ON candidates.accommodation_id = omc_accommodation_season_period.accommodation_id
AND date BETWEEN '2013-08-13' AND '2013-08-15'
AND omc_accommodation_season_period.date <> 0
LEFT JOIN omc_accommodation_room_extra_quota eq1
ON (candidates.accommodation_id = eq1.accommodation_id
AND room_1 = eq1.room_type_id
AND eq1.date=omc_accommodation_season_period.date)
LEFT JOIN omc_accommodation_room_extra_quota eq2
ON (candidates.accommodation_id = eq2.accommodation_id
AND room_2 = eq2.room_type_id
AND eq2.date=omc_accommodation_season_period.date)
LEFT JOIN omc_accommodation
ON candidates.accommodation_id = omc_accommodation.id
LEFT JOIN omc_accommodation_room_pricelist r1_price
ON (candidates.accommodation_id = r1_price.accommodation_id
AND room_1= r1_price.room_type_id)
LEFT JOIN omc_accommodation_room_pricelist r2_price
ON (candidates.accommodation_id = r2_price.accommodation_id
AND room_1 = r2_price.room_type_id)
WHERE
r1_price.season_id = omc_accommodation_season_period.season_id
AND
r2_price.season_id = omc_accommodation_season_period.season_id
GROUP BY candidates.accommodation_id, omc_accommodation_season_period.date
Problem is just to calculate the total price of each room..
Help me fix it up..
Many thanks in advance
SELECT rsp1.date, rsp1.season_id, r1.hotel_id, r1.id AS room_1, rp1.price_normal AS room_1_price, SUM(rp1.price_normal) AS room_1_total, r2.id AS room_2, rp2.price_normal AS room_2_price
FROM
omc_hotel_room r1
LEFT JOIN omc_hotel_room r2 ON r1.hotel_id = r2.hotel_id
INNER JOIN omc_hotel_room_pricelist rp1 ON r1.hotel_id = rp1.hotel_id AND r1.id = rp1.room_type_id
INNER JOIN omc_hotel_room_pricelist rp2 ON r1.hotel_id = rp1.hotel_id AND r2.id = rp2.room_type_id
LEFT JOIN omc_hotel_season_period rsp1 ON r1.hotel_id = rsp1.hotel_id
WHERE
r1.pax_max = 1 AND
rp1.price_normal <> 0 AND
r2.pax_max = 2 AND
rp2.price_normal <> 0 AND
rsp1.date BETWEEN '2013/08/13' AND '2013/08/15'
GROUP BY r1.hotel_id, rsp1.date

mysql select query

I've got 2 tables: interviews & interview_keywords.
An interview has 5 sorted keywords. I need a list of interviews with specified keywords in the right positions of the sorted list. This is what I've got so far, which isn't working:
SELECT i.id,
i.title
FROM interviews AS i
LEFT JOIN interview_keywords AS ik ON i.id = ik.interview_id
WHERE i.cat_id = 1
AND ( (ik.keyword_id = 39 AND ik.sort = 1)
AND (ik.keyword_id = 33 AND ik.sort = 2)
AND (ik.keyword_id = 51 AND ik.sort = 3)
AND (ik.keyword_id = 96 AND ik.sort = 4)
AND (ik.keyword_id = 97 AND ik.sort = 5))
SELECT i.id, i.title
FROM interviews i
INNER JOIN interview_keywords ik1
ON ik1.interview.id = i.id
AND ik.keyword_id = 39
AND ik1.sort = 1
INNER JOIN interview_keywords ik2
ON ik2.interview.id = i.id
AND ik2.keyword_id = 33
AND ik2.sort = 2
INNER JOIN interview_keywords ik3
ON ik3.interview.id = i.id
AND ik3.keyword_id = 51
AND ik3.sort = 3
INNER JOIN interview_keywords ik4
ON ik4.interview.id = i.id
AND ik4.keyword_id = 96
AND ik4.sort = 4
INNER JOIN interview_keywords ik5
ON ik5.interview.id = i.id
AND ik5.keyword_id = 97
AND ik5.sort = 5
WHERE i.cat_id = 1