I need help with an advanced SQL-query (MSSQL 2000).
I have a table called Result that lists athletics 100 and 200 meter race-times. A runner can have several racetimes but I want to show only the best time from each runner at each event.
The Result-table contains five columns, Result_id, athlete_id, result_time, result_date, event_code. So athlete_id must be unique when I list the values and result_time must be the fastest (lowest) value. Also I want to be able to choose if event_code should be "= 1" or "= 2", since 100 and 200 meter resulttimes are mixed in the same table.
I asked a similiar question a few days ago, but without the event_code condition.
This is the answer we came up with.
select r.*
from result r
inner join (
select athelete_id, min(result_time) as FastestTime
from result
group by athelete_id
) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
Any ideas how I can add the event_code condition to this snippet?
Try this:
select r.*
from result r
inner join (
select athelete_id, min(result_time) as FastestTime
from result
where event_code = 1
group by athelete_id
) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
Include the event code in the output of the subquery. Then you can show all events at the same time or choose them in an outer where clause:
select r.*
from result r inner join
(select athlete_id, event_code, min(result_time) as FastestTime
from result
group by athlete_id, event_code
) rm
on r.athelete_id = rm.athlete_id and
r.result_time = rm.FastestTime and
r.event_code = rm.event_code
-- where event_code = xx
The last line is an optional WHERE clause in case you want just one event at a time.
Related
I want make a leaderboard from my database, I already make a code but the sql says error
"SET #a1 = (SELECT SUM(d.poin_diskusi)
FROM diskusi d
GROUP BY d.id_akun)
MySQL said: Documentation
#1242 - Subquery returns more than 1 row"
heres my sql query :
SET #a1 = (SELECT SUM(d.poin_diskusi)
FROM diskusi d
GROUP BY d.id_akun);
SET #a2 = (SELECT SUM(j.nilai_jawaban)
FROM jawaban j
GROUP BY j.id_akun);
SET #hasil = #a1 + #a2;
SELECT #hasil
Thank you !
this is an example data in table jawaban:
this is an example data in table diskusi:
and my desired answer:
where tera123 have 135 TOTAL(d.poin_diskusi+j.nilai_jawaban) and david123 have 90 TOTAL(d.poin_diskusi+j.nilai_jawaban)
the point is to show TOTAL for every user
It looks to me (without looking at your images; if you want to show information, please provide it in text) like you want something like:
select id_akun, sum(point_value) as total_points from (
select id_akun, sum(poin_diskusi) as point_value
from diskusi group by id_akun
union all
select id_akun, sum(nilai_jawaban) as point_value
from jawaban group by id_akun
) as point_values
group by id_akun
The problem are the GROUP BY keywords. Inside the images you provided with example data, one can see that there are multiple entries for the columns jawaban.id_akun and diskusi.id_akun. Because of that, both SELECT will return multiple rows as result, for each different value of the id columns one summed up row. Try it without the GROUP BY clause.
I have two tables:
table 1.a
id--entry_date-amount
============================
2---2016-04-14--$400
3---2016-04-14--$400
4----2017-07-14--$200
5---2017-07-14--$500
6---2017-05-14--$600
7----2017-06-18--$100
table 2.b
id--entry_date
===========================
2---2016-04-14--$230
3---2016-04-14--$230
4----2017-07-14--$567
5---2017-07-14--$600
6---2017-05-14--$560
7----2017-06-18--$90
8---2016-04-14--$100
from the two tables how can i get count with montwise
my desired result:
month_name--total(count form table a)--total(count form table b)--amount(table a)--amount(table b)
========================================================
April,16-----------2-------------------3---$800-$500
May,17-----------1-------------------1 --$600--$700
June,17-----------2-------------------2--$100--$800
July,17-----------2-------------------2---$700-$400
this is the demo data.
I want to show data from two tables in a single query month wise.
How can i do this?
I tried:
SELECT MONTHNAME(r.entry_date),r.a_total FROM(
SELECT
IFNULL((SELECT COUNT(tr.id) AS amount FROM a AS tr WHERE MONTH(tr.entry_date)=MONTH(t.entry_date)),0) AS a_total
,t.entry_date
FROM(SELECT tr.id,tr.entry_date
FROM a AS tr
WHERE DATE(tr.entry_date) BETWEEN '2017-07-01' AND '2018-06-30') t
GROUP BY MONTH(t.entry_date)) r
But takes 58 seconds for simple query. How can i make this in a simple query?
You can get the counts and sum from each table individually, then use UNION to combine the two result sets into one result set. Something like this :
SELECT Month_name,
SUM(aCount) AS aCount,
SUM(bCount) AS bCount,
SUM(aAmount) AS aAmount,
SUM(bAmount) AS bAmount
FROM
(
SELECT
MONTHNAME(a.entry_date) AS Month_name,
COUNT(a.id) AS aCount,
0 AS bCount,
SUM(a.amount) AS aAmount,
0 AS bAmount
FROM a
GROUP BY MONTHNAME(a.entry_date)
UNION ALL
SELECT
MONTHNAME(b.entry_date) AS Month_name,
0 AS aCount,
COUNT(b.id) AS bCount,
0 AS aAmount,
SUM(b.amount) AS bAmount
FROM b
GROUP BY MONTHNAME(b.entry_date)
) AS t
GROUP BY Month_Name;
live demo
user9131497 has a good design for the big picture. However, I would suggest stuff like this for handling the dates:
SELECT DATE_FORMAT(entry_date, "%M,%y") AS 'Month',
COUNT(*) AS 'aCount'
FROM a
GROUP BY LEFT(entry_date, 7) -- eg, "2017-03"
Try that to see what I mean.
Note that this will work beyond a year. Or did you need January values from all years to be combined?? -- That's what your solution and user9131497's will do. Mine keeps them separate.
I am running this query on my website in order to find a ToDo list based on specific criteria. But it runs too slow and it is probably possible to write it in another way.
SELECT * FROM lesson WHERE
id IN
(SELECT `lesson_id` FROM `localization_logging`
WHERE `language_id` = 2 AND `action_id` = 1)
AND `id` NOT IN
(SELECT `lesson_id` FROM `localization_logging`
WHERE `language_id` = 2 AND `part_id` = 1 AND `action_id` = 6)
What the query does is that it looks in the lesson table to find all lesson list names and then checks if a specific task is done. If the task is done in one todo than show it in the next. Action 1 is done but not action 6 in this case.
I hope I'm explaining this good enough. On my local machine the query takes 1.8 seconds, and sometimes I have to print multiple lists next to each others and then it takes 1.8 times the lists which makes the page load super slow.
Something like this for mark id as completed:
SELECT l.*, SUM(ll.action_id=6) completed FROM lesson l
INNER JOIN localization_logging ll ON ll.lesson_id = l.id
WHERE ll.language_id = 2 AND
(
ll.action_id = 1
OR
ll.action_id = 6 AND ll.part_id == 1
)
GROUP BY l.id
And now we can wrap it with:
SELECT t.* FROM (...) t WHERE t.completed = 0
You'll usually get faster queries filtering rows with INNER/LEFT JOIN, but you need to test it.
SELECT lesson.* FROM lesson
INNER JOIN localization_logging task1
ON lesson.id = task1.lesson_id
LEFT JOIN localization_logging task2
ON lesson.id = task2.lesson_id
AND task2.language_id = 2
AND task2.part_id = 1
AND task2.action_id = 6
WHERE task1.language_id = 2
AND task1.action_id = 1
AND task2.lesson_id IS NULL
Second table is joined on multiple conditions, but have to list them within ON clause because only results that were in result "force joined" as nulls (left join means left side stays no matter what) are required.
Btw. You'll get multiple rows from lesson if task1 condition is not limiting results to one row - GROUP BY lesson.id then.
I have three tables named issue_details, nature_payments, and rci_records. Now I have this query which joins this three tables.
SELECT issue_details.issue_date AS Date,
issue_details.check_no AS Check_No,
payees.payee_name AS Name_payee,
nature_payments.nature_payment AS Nature_of_Payment,
issue_details.issue_amount AS Checks_issued,
issue_details.nca_balance AS Nca_balance
FROM
issue_details
INNER JOIN
nature_payments ON
issue_details.nature_id = nature_payments.nature_id
INNER JOIN
payees ON
issue_details.payee_id = payees.payee_id
ORDER BY Date Asc, Check_no ASC
On my column in Nca_balance, this is a computed differences of every issuances of check. But you may not know what really the process of how I got the difference but to make it simple, let's say that I have another query
that dynamically get also the difference of this nca_balance column. Here is the query:
SELECT r.*,
(#tot := #tot - issue_amount) as bank_balance
FROM (SELECT #tot := SUM(nca_amount) as nca_total FROM nca
WHERE account_type = 'DBP-TRUST' AND
year(issue_date) = year('2015-01-11') AND
month(issue_date) = month('2015-01-11')
)
vars CROSS JOIN issue_details r
WHERE r.account_type = 'DBP-TRUST' AND
r.issue_date = '2015-01-11'
ORDER BY r.issue_date, r.check_no
I know it you may not get my point but I just want to replace the first query of the line
issue_details.nca_balance AS Nca_balance
with my own computation on my second query.
Please help me combine those two query into a single query. Thanks
I am trying to calculate the difference of values list coming from a database.
I would like to achieve it using php or mysql, but I do not know how to proceed.
I have a table named player_scores. One of its rows contains the goals scored.
Ex.
pl_date pl_scores
03/11/2014 18
02/11/2014 15
01/11/2014 10
I would like to echo the difference between the goals scored during the matches played in different dates.
Ex:
pl_date pl_scores diff
03/11/2014 18 +3
02/11/2014 15 +5
01/11/2014 10 no diff
How can I obtain the desired result?
You seem to want to compare a score against the score on a previous row.
Possibly simplest if done using a a sub query that gets the max pl_date that is less than the pl_date for the current row, then joining the results of that sub query back against the player_scores table to get the details for each date:-
SELECT ps1.pl_date, ps1.pl_scores, IF(ps2.pl_date IS NULL OR ps1.pl_scores = ps1.pl_scores, 'no diff', ps1.pl_scores - ps1.pl_scores) AS diff
FROM
(
SELECT ps1.pl_date, MAX(ps2.pl_date) prev_date
FROM player_scores ps1
LEFT OUTER JOIN player_scores ps2
ON ps1.pl_date > ps2.pl_date
GROUP BY ps1.pl_date
) sub0
INNER JOIN player_scores ps1
ON sub0.pl_date = ps1.pl_date
LEFT OUTER JOIN player_scores ps2
ON sub0.prev_date = ps2.pl_date
There are potentially other ways to do this (for example, using variables to work through the results of an ordered sub query, comparing each row with the value stored in the variable for the previous row)
SELECT score FROM TABLE WHERE DATE = TheDateYouWant
$score = $data['score'];
SELECT score FROM TABLE WHERE date = dateYouWant
$difference = $score - $data['score'];
Something like this?
You could use two queries, one to get the value to use in the comparison (in the example below is the smaller number of scores) and the second one to get the records with a dedicated column with the difference:
SELECT MIN(pl_scores);
SELECT pl_date, pl_scores, (pl_scores - minScore) as diff FROM player_scores;
Or, using a transaction (one query execution php side):
START TRANSACTION;
SELECT MIN(Importo) FROM Transazione INTO #min;
SELECT Importo, (Importo - #min) as diff FROM Transazione;
select *,
coalesce(
(SELECT concat(IF(t1.pl_scores>t2.pl_scores,'+',''),(t1.pl_scores-t2.pl_scores))
FROM tableX t2 WHERE t2.pl_date<t1.pl_date ORDER BY t2.pl_date DESC LIMIT 1)
, 'no data' ) as diff
FROM tableX t1
WHERE 1
order by t1.pl_date DESC