Getting count from complicated mysql statement - mysql

I'm trying to get the count of unique questions from the following mysql statement but every time I try to add count(q.id) as questionCount the statement only returns one result. I'm obviously doing something wrong but I can't figure out what it is.
http://www.sqlfiddle.com/#!2/34906/58
Hope somebody can help.
Steve

Just edit 2nd line of your query to this one:
select
count(distinct FinalQA.QUESTION_ID) from.....

It appears you want the total questions "stamped" on every row... for example you are auto-generating a test and want it to show "Out of 5 questions" in the output. To simplify this, since you KNOW you want 5 questions via your WHERE clause, I would slightly adjust it to...
select
FinalQA.*
from
( select
5 as TotalQuestionsOffered,
QWithAllAnswers.*,
... rest of query ) FinalQA
where
FinalQA.ARankSeq <= FinalQA.TotalQuestionsOffered

Related

MySQL : Count returning double the number of entries when using distinct

So I do a count like so
select distinct count(prod.id) from product as prod....
I get back 175590
I do a select like so
select distinct prod.id from product as prod.... (rest of the query is exactly the same)
and I limit it. Now if I limit the query to return anything over the half way point it returns nothing. It appears as if count is returning double the number of entries each time.
Does anyone know of anything that may be causing this?
Thanks
Tracey
The DISTINCT keyword tells MySQL to strip the duplicate rows from the result set. Because SELECT COUNT(prod.id) returns a single row (I guess this, I cannot tell for sure until I see the complete query), adding DISTINCT in front of COUNT() does not change its behaviour in any way.
What you probably want is SELECT COUNT(DISTINCT prod.id) and that's a totally different thing. It removes the duplicate values of prod.id before counting them.
Your first query is counting how many prod.id's there are.
Your second query is showing all distinct prod.id's.
This is quite different.
If you were to do the second query without the distinct key word the number would be the same.

mysql select distinct *

I'd rather post an image here, but it says that I don't have enough reputation to do it.
I tried to find something similar to my question, but there are to much "distinct" and "group by" to find something useful... "distinct *" in search gives the same, as "distinct"..
Here is link to xlsx-file with table with source example data and table with desired result
Source example data - is a simplified result of some complex query.
The question is here:
I'd like to apply to this result of select some grouping, which gives query "select distinct * from table_below".
But, this variant is not very good for performance reason. My original non-simplified table has about 4000 rows, and 10 columns. So, "select distinct *" takes 20 sec to give needed result.
To be clear, I want to make grouping by 4-th column, but within every "column_id", as shown in xlsx attached file.
Thanks in advance
It is better to write out the coloumn names. Could you try this?
SELECT DISTINCT coming_id, spare_id ,spare_sum, product_id
FROM Table
Order by coming_id, spare_id, product_id

MySQL: Include COUNT of SELECT Query Results as a Column (Without Grouping)

I have a simple report sending framework that basically does the following things:
It performs a SELECT query, it makes some text-formatted tables based on the results, it sends an e-mail, and it performs an UPDATE query.
This system is a generalization of an older one, in which all of the operations were hard coded. However, in pushing all of the logic of what I'd like to do into the SELECT query, I've run across a problem.
Before, I could get most of the information for my text tables by saying:
SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT';
Then, when I needed an extra number for the e-mail, also do:
SELECT COUNT(*) FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
Now, I no longer have the luxury of multiple SELECT queries. What I'd like to do is something like:
SELECT Tabl.Name, Tabl.Address, COUNT(Results.UID) AS Totals
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
AND Results.TimeLogged='Noon'
WHERE Status='URGENT';
This, at least in my head, says to get a total count of all the rows that were SELECTed and also have some conditional.
In reality, though, this gives me the "1140 - Mixing of GROUP columns with no GROUP columns illegal if no GROUP BY" error. The problem is, I don't want to GROUP BY. I want this COUNT to redundantly repeat the number of results that SELECT found whose TimeLogged='Noon'. Or I want to remove the AND clause and include, as a column in the result of the SELECT statement, the number of results that that SELECT statement found.
GROUP BY is not the answer, because that causes it to get the COUNT of only the rows who have the same value in some column. And COUNT might not even be the way to go about this, although it's what comes to mind. FOUND_ROWS() won't do the trick, since it needs to be part of a secondary query, and I only get one (plus there's no LIMIT involved), and ROW_COUNT() doesn't seem to work since it's a SELECT statement.
I may be approaching it from the wrong angle entirely. But what I want to do is get COUNT-type information about the results of a SELECT query, as well as all the other information that the SELECT query returned, in one single query.
=== Here's what I've got so far ===
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
This does use sub-SELECTs, which I was initially hoping to avoid, but now realize that hope may have been foolish. Plus it seems like the COUNTing SELECT sub-queries will be less costly than the main query since the COUNT conditionals are all on one table, but the real SELECT I'm working with has to join on multiple different tables for derived information.
The key realizations are that I can GROUP BY NULL, which will return a single result so that COUNT(*) will actually catch everything, and that I can force a correlation to this column by just faking a Bonus column with 0 on both tables.
It looks like this is the solution I will be using, but I can't actually accept it as an answer until tomorrow. Thanks for all the help.
SELECT Tabl.Name, Tabl.Address, Results.Totals
FROM Databas.Tabl
LEFT JOIN (SELECT COUNT(*) AS Totals, 0 AS Bonus
FROM Databas.Tabl
WHERE TimeLogged='Noon'
GROUP BY NULL) Results
ON 0 = Results.Bonus
WHERE Status='URGENT';
I figured this out thanks to ideas generated by multiple answers, although it's not actually the direct result of any one. Why this does what I need has been explained in the edit of the original post, but I wanted to be able to resolve the question with the proper answer in case anyone else wants to perform this silly kind of operation. Thanks to all who helped.
You could probably do a union instead. You'd have to add a column to the original query and select 0 in it, then UNION that with your second query, which returns a single column. To do that, the second query must also select empty fields to match the first.
SELECT Cnt = 0, Name, Address FROM Databas.Tabl WHERE Status='URGENT'
UNION ALL
SELECT COUNT(*) as Cnt, Name='', Address='' FROM Databas.Tabl WHERE Status='URGENT' AND TimeLogged='Noon';
It's a bit of a hack, but what you're trying to do isn't ideal...
Does this do what you need?
SELECT Tabl.Name ,
Tabl.Address ,
COUNT(Results.UID) AS GrandTotal,
COUNT(CASE WHEN Results.TimeLogged='Noon' THEN 1 END) AS NoonTotal
FROM Databas.Tabl
LEFT JOIN Databas.Tabl Results
ON Tabl.UID = Results.UID
WHERE Status ='URGENT'
GROUP BY Tabl.Name,
Tabl.Address
WITH ROLLUP;
The API you're using to access the database should be able to report to you how many rows were returned - say, if you're running perl, you could do something like this:
my $sth = $dbh->prepare("SELECT Name, Address FROM Databas.Tabl WHERE Status='URGENT'");
my $rv = $sth->execute();
my $rows = $sth->rows;
Grouping by Tabl.id i dont believe would mess up the results. Give it a try and see if thats what you want.

output sql statement is grouped

I have a little problem, have the following statement in mysql:
SELECT cmfilm.*, cmgenre.titel AS genretitel, cmvertoning.*, cmzaal.titel AS zaaltitel
FROM cmfilm
LEFT JOIN cmvertoning ON cmvertoning.film_id=cmfilm.id
LEFT JOIN cmgenre ON cmfilm.genre_id=cmgenre.id
LEFT JOIN cmzaal ON cmvertoning.zaal_id=cmzaal.id
WHERE cmvertoning.id IN(74,74,74,74)
ORDER BY cmfilm.id ASC
because i'm asking the same id 4 times it only gives me 1 result. But i would like to have the result to be returned 4 times, as i asked it to do. Anyone who knows how to solve this?
Maybe it would be better to achieve this on the application side - put returned rows in a map, then iterate over the ids you wanted and get appropriate rows from a map. Because there is another problem - the rows might not be in the order in which order you specified the ids (BTW. this row ordering problem can be solved also using field).
The UNION solution would work too. But, honestly, I think that you have some design problem if you need to fetch the same rows multiple times.
You did not ask for 4 rows, you asked for any rows where id is 74, 74, 74 or 74 - of which there is only one.
The real question is, why do you want the same row 4 times?
I don't think you can acomplish that without some sort of a loop, or by using the UNION ALL statement.

Sql count without duplication in statment

i have an sql query that selects a bunch of data. I would also like to get the number of records selected by the query (before i limit it). All the examples i have seen of the count statment duplicated the select. My select statment is about 50 lines long and i would rarther not duplicate it.
Thanks
Your question would be easier to answer if you could give us an example SQL statement, however, from what you have said so far, the following should be correct:
Select Columns, Count(Distinct Value) From Table Where x=y Group By Columns
Yes.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows
It isn't really possible to get the number of rows that a query would return without running it or a version of it.
There's sql_calc_found_rows which will let you put a limit clause on the statement and return the total number of rows it would have found had there not been a limit clause in a subsequent call to found_rows(), but it's expensive.
Thanks everyone, i was just trying out sql_calc_found_rows, and your dam right Nick, it is expensive. I think ill just create a separte query, thanks