I have those two tables:
users:
And playertimes:
(I know jumps and style should be int and not varchar() but that's not what I'm trying to solve)
I have a query, which is supposed to return the following results within the resultset:
name - retrieved using JOIN with auth
time
style
Here's my current query:
SELECT p.style, p.time, u.name FROM playertimes p JOIN users u ON p.auth = u.auth WHERE p.map = 'bhop_good' ORDER BY p.time ASC;
Here's the result I'm getting with the query above:
At this moment, the table can only contains two possible values of style which are 0 or 1. What I'm looking for, is to make style a DISTINCT, so in my case, I want to only get 2 results (one row per a value of style) for the query above, which should look like the following screenshot:
I'd like to receive help, thanks!
It looks like you want the style row for each distinct value of style having the smallest time value.
You get that like so. It takes two steps. The first determines the smallest time for each value
SELECT style, MIN(time) time
FROM playertimes
GROUP BY style
The second step gets the actual playertimes row corresponding to that time.
SELECT p.style, s.time, p.auth
FROM playertimes p
JOIN (
SELECT style, MIN(time) time
FROM playertimes
GROUP BY style
) s ON p.style = s.style AND p.time = s.time
Finally, you can join that lot to your users table to turn your auth column into a name column.
SELECT p.style, s.time, u.name
FROM playertimes p
JOIN (
SELECT style, MIN(time) time
FROM playertimes
GROUP BY style
) s ON p.style = s.style AND p.time = s.time
JOIN users.u ON p.auth = u.auth
And, of course, once you have a working query you can add a WHERE clause to it, like this one.
WHERE p.map = 'some constant'
Related
Is it possible to use two "select" in the same query?
I tried it but got the syntax error several times.
My query example:
SELECT
comp.id,
comp.document,
comp.dateStart,
comp.companyName,
comp.fantasyName,
comp.legalNature,
comp.mainActivity,
comp.situation,
comp.shareCapital,
comp.idCompanyStatus,
pp.userCredentialId,
uc.name,
cs.name AS 'nameStatus',
cs.color AS 'colorStatus',
cs.description,
comp.idPurchasedProduct,
comp.actived,
comp.createAt,
comp.updateAt,
comp.phone
FROM `PurchasedProduct` pp
INNER JOIN
`Company` comp on comp.idPurchasedProduct = pp.id
INNER JOIN
`UserCustomer` uc on pp.userCredentialId = uc.credentialId
INNER JOIN
`CompanyStatus` cs on cs.id = comp.idCompanyStatus
WHERE
comp.actived = 1
LIMIT 0,5;
SELECT COUNT(id) AS totalItems, CEILING(COUNT(id) / 10) AS totalPages FROM Company;
I would like the result shown to be all queries on the screen.
Basically, what I want is that the result shown when executing the query is the first and second "select" together.
I really don't know how or don't understand how to do this.
Example:
first result with seconde result
I want to show both results at once.
The documents is fake, not real. Only for demo.
You should be able to do by having the second query as its own JOIN query. Since there is no group by, it is only returning a single row. By no join condition, the value will be available for every row otherwise. So you SHOULD be able to get by doing
select
[ all your other columns ],
JustCounts.TotalItems,
JustCounts.TotalPages
from
[PurchasedProduct and all your other joins]
JOIN ( SELECT
COUNT(id) AS totalItems,
CEILING(COUNT(id) / 10) AS totalPages
FROM Company ) as JustCounts
where
[rest of your original query]
My code sample for get total total_stamp, i need with active and inactive. My stamp table have current_status row for active and inactive
SELECT r.*
, COUNT(s.current_status) total_stamp
FROM tbl_registers r
LEFT
JOIN tbl_stamps s
ON r.register_id = s.register_id
WHERE r.ins_id = 1
GROUP
BY r.register_id
ORDER BY r.register_name_en ASC
, s.stamp_name_en ASC
Current output like that, I need another more column line one is total_active another is total inactive with single query.
SELECT r.*,
COUNT(s.current_status),
SUM(current_status='something meaning active') active,
SUM(current_status='something meaning inactive') inactive,
...
should do the trick. Why? because expressions like current_status='something meaning inactive' in MySQL have the value 0 meaning false, or 1 meaning true. So SUM() adds up the number of true items.
I think the best way to achieve this would be to split your LEFT JOIN up into two separate LEFT JOINS. One to the table where active and another where inactive. This way you will be able to sum the three separately. Does that make sense? Something like this:
SELECT r.*, sActive.total + sInactive.total as total_stamp, sActive.total as active_stamp, sInactive.total as inactive_stamp
FROM tbl_registers as r
LEFT JOIN (
SELECT register_id, COUNT(*) as total
FROM tbl_stamps
WHERE s.current_status = 'active'
GROUP BY register_id
) as sActive ON sActive.register_id = r.register_id
LEFT JOIN (
SELECT register_id, COUNT(*) as total
FROM tbl_stamps
WHERE s.current_status = 'inactive'
GROUP BY register_id
) as sInactive ON sInactive.register_id = r.register_id
GROUP BY r.register_id
I've got two tables, for example: Teacher and Pupil and table LastViewedPupil with fields who watched him and when (teacherId & pupilId). So I want to return the list of Pupils that was ordered by last viewed date, but there are not all pupils inside LastViewedPupil, but last few for example, I want to show after that ordered by date all left records no matter in wich order, how can I do that?
I can do without last part like
select * from Pupil as p, (
select * from LastViewedPupil lvp where lvp.teacherId = 5 ORDER BY lastViewDate
) as lvp where lvp.pupilId = p.pupilId;
Or should I add corresponding records in LastViewDatePupil for all pupils or need to Join table itself (sounds awkward)?
You should try this one:
SELECT p.*
LEFT JOIN LastViewedPupil lvp ON p.id = lvp
WHERE lvp.teacher_id = 5
ORDER BY lvp.lastViewDate DESC
I'm not sure if that query puts NULL at the beginning or at the end. If that doesn't order the results properly, try this other. I used a CASE for reordering data
SELECT p.*,
CASE WHEN lvp.lvp.lastViewDate IS NULL THEN 1 ELSE 0, END AS notNullfirst FROM Pupil p
LEFT JOIN LastViewedPupil lvp ON p.id = lvp
WHERE lvp.teacher_id = 5
ORDER BY notNullfirst, lvp.lastViewDate DESC
Take the following:
SELECT
Count(a.record_id) AS newrecruits
,a.studyrecord_id
FROM
visits AS a
INNER JOIN
(
SELECT
record_id
, MAX(modtime) AS latest
FROM
visits
GROUP BY
record_id
) AS b
ON (a.record_id = b.record_id) AND (a.modtime = b.latest)
WHERE (((a.visit_type_id)=1))
GROUP BY a.studyrecord_id;
I want to amend the COUNT part to display a zero if there are no records since I assume COUNT will evaluate to Null.
I have tried the following but still get no results:
IIF(ISNULL(COUNT(a.record_id)),0,COUNT(a.record_id)) AS newrecruits
Is this an issue because the join is on record_id? I tried changing the INNER to LEFT but also received no results.
Q
How do I get the above to evaluate to zero if there are no records matching the criteria?
Edit:
To give a little detail to the reasoning.
The studies table contains a field called 'original_recruits' based on activity before use of the database.
The visits tables tracks new_recruits (Count of records for each study).
I combine these in another query (original_recruits + new_recruits)- If there have been no new recruits I still need to display the original_recruits so if there are no records I need it to evalulate to zero instead of null so the final sum still works.
It seems like you want to count records by StudyRecords.
If you need a count of zero when you have no records, you need to join to a table named StudyRecords.
Did you have one? Else this is a nonsense to ask for rows when you don't have rows!
Let's suppose the StudyRecords exists, then the query should look like something like this :
SELECT
Count(a.record_id) AS newrecruits -- a.record_id will be null if there is zero count for a studyrecord, else will contain the id
sr.Id
FROM
visits AS a
INNER JOIN
(
SELECT
record_id
, MAX(modtime) AS latest
FROM
visits
GROUP BY
record_id
) AS b
ON (a.record_id = b.record_id) AND (a.modtime = b.latest)
LEFT OUTER JOIN studyrecord sr
ON sr.Id = a.studyrecord_id
WHERE a.visit_type_id = 1
GROUP BY sr.Id
I solved the problem by amending the final query where I display the result of combining the original and new recruits to include the IIF there.
SELECT
a.*
, IIF(IsNull([totalrecruits]),consents,totalrecruits)/a.target AS prog
, IIf(IsNull([totalrecruits]),consents,totalrecruits) AS trecruits
FROM
q_latest_studies AS a
LEFT JOIN q_totalrecruitment AS b
ON a.studyrecord_id=b.studyrecord_id
;
I have this query:
SELECT p.text,se.name,s.sub_name,SUM((p.volume / (SELECT SUM(p.volume)
FROM phrase p
WHERE p.volume IS NOT NULL) * sp.position))
AS `index`
FROM phrase p
LEFT JOIN `position` sp ON sp.phrase_id = p.id
LEFT JOIN `engines` se ON se.id = sp.engine_id
LEFT JOIN item s ON s.id = sp.site_id
WHERE p.volume IS NOT NULL
AND s.ignored = 0
GROUP BY se.name,s.sub_name
ORDER BY se.name,s.sub_name
There are a few things I want to do with it:
1) The end of the calculation for 'index', I multiple it all by sp.position, then get it's SUM. If there is NO MATCH in the first LEFT JOIN 'position', I want to give sp.position a value of 200. So basically if in the 'phrase' table I have an ID=2, but that does not exist in sp.phrase_id in the entire 'position' table, then sp.position=200 for the 'index' calculation, otherwise it will it will be whatever value is stored in the 'position' table. I hope that makes sense.
2) I do a GROUP BY se.name. I would like to actually SUM the entire 'index' values for similar se.name fields. So in the resultset as it stands now, if there were 20 p.text rows with the same se.name, I would like to SUM the index column for the same se.name(s).
I am more of a PHP guy, but trying to learn more MySQL. I have become a big believer in making the DB do as much of the work as possible instead of trying to manipulate the dataset after it's been returned.
I hope the questions were clear. Anyways, can both 1) and 2) be done? There's much more I want to modify this query to do, but I think if I need more help in the future on it, it would require a different question.
The position table has a engines_id, phrase_id, item_id which will make it a unique entry. The value I am trying to calculate is the sp.position value. But there are cases when there is no entry for these IDs combined. If there is no entry for the combo of 3 IDs I just listed, I would like to use sp.position=200 in my calculation.
How's this:
select x.name, sum(index) from
(
SELECT p.text,se.name,s.sub_name,SUM((p.volume / (SELECT SUM(p.volume)
FROM phrase p
WHERE p.volume IS NOT NULL) * if(sp.position is null,200,sp.position)))
AS `index`
FROM phrase p
LEFT JOIN `position` sp ON sp.phrase_id = p.id
LEFT JOIN `engines` se ON se.id = sp.engine_id
LEFT JOIN item s ON s.id = sp.site_id
WHERE p.volume IS NOT NULL
AND s.ignored = 0
GROUP BY se.name,s.sub_name
ORDER BY se.name,s.sub_name
)x
GROUP BY x.name
Try the following:
1.) Use IFNULL(), in your case IFNULL(sp.position, 200)
2.) I am not entirely clear on this part, but it seems like you already have part of what you are asking.