2

How can I write this in one query ?

I have two tables one likes this called (late):

id     name     S_id
1       A         6
2       A         6
3       B         5
4       C         8
5       A         6
6       A         6
7       C         8
8       C         8

The other one likes this called (absent):

id     name     S_id
1       A         6
2       A         6
3       A         6
4       A         6
5       A         6
6       A         6
7       B         5
8       c         8

I want the results like this table:

where (count late) counts times of late and (count absent) counts time of absents.

name    Count late    Count absent
 A          4              6
 B          1              1
 C          3              1

I tried something like this:

this didn't work !

SELECT 
*
FROM
(SELECT name, COUNT(*) AS '# count absent' FROM absent GROUP BY s_id)  t1 
INNER JOIN
(SELECT name, COUNT(*) AS '# count Late' FROM late   GROUP BY s_id)  t2
ON t1.s_id = t2.s_id ;

5 Answers 5

1

Use Union of the two tables: lates and absents... then sum up the number of lates and absents.

Try this:

SELECT 
    SUM(tardies) as 'total_lates', SUM(absences) as 'total_absences', name, s_id
FROM
    ((SELECT
        COUNT(*) as 'tardies',
        0 as 'absences',
        name,
        s_id
    FROM 
        lates
    GROUP BY
        s_id
    )
UNION
    (SELECT 
        0 as 'tardies',
        COUNT(*) as 'absences',
        name,
        s_id
     FROM
        absents
     GROUP BY
        s_id
    )
)
as maintable
GROUP by s_id
ORDER BY name
Sign up to request clarification or add additional context in comments.

1 Comment

nope... only one record per person... with both "late counts" and "absent counts" for each record... there is a group by for the maintable...
0

If you need join on s_id you must select these column in subselect

  SELECT 
  *
  FROM
  (SELECT s_id, name, COUNT(*) AS '# count absent' 
      FROM absent GROUP BY s_id)  t1 
  LEFT JOIN
  (SELECTs_id,  name, COUNT(*) AS '# count Late' 
      FROM late   GROUP BY s_id)  t2
  ON t1.s_id = t2.s_id ;

otherwise the resulting select can't be join because there aren't the columns for this

2 Comments

But this will eliminate names which were either only absent or only late.
@TimBiegeleisen thaks correte update the left join .. and eventully the OP could use a table for all the name and left join the table late and absentt for avoid missing name
0
SELECT 
  (case when t1.name is not null then t1.name else t2.name end) as name,t1.absent,t2.late
  FROM
  (SELECT name, COUNT(*) AS 'absent' 
      FROM absent GROUP BY name)  t1 
  FULL JOIN
  (SELECT  name, COUNT(*) AS 'late' 
      FROM late   GROUP BY name)  t2
  ON t1.name = t2.name ;

Try this. I haven't tried. Hope it works.

2 Comments

I haven't tried ... Had you tried you would have discovered that there is no full join in MySQL.
Thanks it had worked,but without full join I only used join .
0

You need a full outer join here to make sure that you retain people who were either late or absent, but not both. Well, MySQL has no built in full outer join support, but it can be simulated:

SELECT t1.name,
       t2.late_cnt,
       t1.absent_cnt
FROM
(SELECT s_id, name, COUNT(*) AS absent_cnt
  FROM absent GROUP BY s_id, name) t1
LEFT JOIN
(SELECT s_id, name, COUNT(*) AS late_cnt
  FROM late GROUP BY s_id, name) t2
    ON t1.s_id = t2.s_id
UNION
SELECT t1.name,
       t2.late_cnt,
       t1.absent_cnt
FROM 
(SELECT s_id, name, COUNT(*) AS absent_cnt
 FROM absent GROUP BY s_id, name) t1
RIGHT JOIN
(SELECT s_id, name, COUNT(*) AS late_cnt
 FROM late GROUP BY s_id, name) t2
    ON t1.s_id = t2.s_id

Comments

0

Please try following. It worked for me.

select 
   coalesce( t1.name,t2.name) name,coalesce( t1.late,0) ,coalesce(t2.[absent],0) 
   from 
      (select name,s_id, count(*) as 'late' from late group by s_id,name ) t1 
   FULL OUTER JOIN
      (select name,s_id, count(*) as 'absent' from [absent] group by s_id,name ) 
   t2 on t1.s_id = t2.s_id 
   order by name

4 Comments

Again, your query will filter off people who were only absent, but not late.
Now this will return both tables records!! Please let me know your view. Thanks!!
There is no full outer join in MySQL. But maybe the OP does not care about this edge case.
I have to thank you because I learn something new from your query. Thanks!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.