1

Need to generate courses list and count

  1. all
  2. unanswered
  3. answered but unchecked

Questions.

My database structure is looking like that

https://docs.google.com/open?id=0B9ExyO6ktYcOenZ1WlBwdlY2R3c

Explanation for some of tables:

  1. answer_chk_results - checked answers table. So if some answer doesn't exist on this table, it means it's unchecked
  2. lesson_questions - lesson <-> question associations (by id) table
  3. courses-lessons - courses <-> lessons associations (by id) table

Executing

    SELECT
    c.ID,
    c. NAME,
    COUNT(lq.id) AS Questions,
    COUNT(
        CASE
        WHEN a.id IS NULL THEN
            lq.id
        END
    ) AS UnAnswered,
    COUNT(
        CASE
        WHEN cr.id IS NULL THEN
            lq.id
        END
    ) AS UnChecked
FROM
    courses c
LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
LEFT JOIN `lesson_questions` lq ON lq.lid = cl.lid
LEFT JOIN answers a ON a.qid = lq.qid
LEFT JOIN answer_chk_results cr ON cr.aid = a.id
GROUP BY
    c.ID

Tested it first on SQL fiddle with sample data. (Real data is huge, so I can't place it on sqlfiddle) It returned some values. Thought works well. But while I test it with real data, see that returns wrong values. Forex, when I manually count, result for all questions count must be 25, but it returns 27. Maybe I'm doing something wrong.

Note MySQL server running on my local machine, so I can give you teamviewer id and password if you want to connect to my desktop remotely and test query with real data.

3
  • The SQLfiddle to which you've linked and the query that you've given in your question are not the same. Which gives the incorrect results on your live data? Commented Aug 30, 2012 at 12:06
  • @eggyal updated link, they are same. Commented Aug 30, 2012 at 12:08
  • 1
    Well, I guess there might be a 1-to-n relation. As we don't see cardinalities anywhere this is a hard guess... Commented Aug 30, 2012 at 12:25

2 Answers 2

1

I suspect the problem is that different joins are resulting in a multiplication of rows. The best way to fix this is by using subqueries along each dimension. The following is a more practical way. Replace the COUNTs in the select with COUNT DISTINCT:

SELECT c.ID, c. NAME,
       COUNT(distinct lq.id) AS Questions,
       COUNT(distinct CASE WHEN a.id IS NULL THEN lq.id END) AS UnAnswered,
       COUNT(distinct CASE WHEN cr.id IS NULL THEN lq.id END) AS UnChecked

Compared to COUNT, COUNT DISTINCT is a resource hog (it has to remove duplicates). However, it will probably work fine for your purposes.

Sign up to request clarification or add additional context in comments.

Comments

0

Use this query

SELECT
    c.ID,
    c.NAME,
    COUNT(lq.id) AS Questions,
    COUNT(IFNULL(a.id),lq.id)AS UnAnswered,
    COUNT(IFNULL(cr.id),lq.id)AS UnChecked,
FROM    courses c
LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
LEFT JOIN `lesson_questions` AS lq ON lq.lid = cl.lid
LEFT JOIN answers a ON a.qid = lq.qid
LEFT JOIN answer_chk_results cr ON cr.aid = a.id
GROUP BY c.ID

Comments

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.