Below query is doing what I need:
SELECT assign.from_uid, assign.aid, assign.message, curriculum.asset,
curriculum.title, curriculum.description
FROM assignment assign
INNER JOIN curriculum_topics_assets curriculum
ON assign.nid = curriculum.asset
WHERE assign.to_uid = 13 AND assign.status = 1
GROUP BY assign.from_uid, assign.to_uid, assign.nid
ORDER BY assign.created DESC
Now I need to get the total count of rows of the result. For example if it is displaying 5 rows the o/p should be like My expected o/p. The query I tried is given below.
SELECT count(description) FROM assignment assign
INNER JOIN curriculum_topics_assets curriculum ON assign.nid = curriculum.asset
WHERE assign.to_uid = 13 AND assign.status = 1
GROUP BY assign.from_uid, assign.to_uid, assign.nid
ORDER BY assign.created DESC
My expected o/p:
count(*)
---------
5
My current o/p:
count(*)
---------
6
2
5
6
6
The easiest solution would be to
place your initial GROUP BY query in a subselect
select the amount of rows retrieved from this subselect
SQL Statement
SELECT COUNT(*)
FROM (
SELECT assign.from_uid
FROM assignment assign
INNER JOIN curriculum_topics_assets curriculum ON assign.nid = curriculum.asset
WHERE assign.to_uid = 13
AND assign.status = 1
GROUP BY
assign.from_uid
, assign.to_uid
, assign.nid
) q
Edit - why doesn't the original query return the results required
It did already prepared what was needed to get the correct result
Your query without grouping returns a resultset of 25 records (6+2+5+6+6)
From these 25 records, you have 5 unique combinations of from_uid, to_uid, nid
Now you don't want to count how many records each combination has (as you did in your example) but how many unique (distinct anyone?) combinations there are.
One solution to this is the subselect I presented but following equivalent statement using a DISTINCT clause might be more comprehensive.
SELECT COUNT(*)
FROM (
SELECT DISTINCT assign.from_uid
, assign.to_uid
, assign.nid
FROM assignment assign
INNER JOIN curriculum_topics_assets curriculum ON assign.nid = curriculum.asset
WHERE assign.to_uid = 13
AND assign.status = 1
) q
Note that my personal preference goes to the GROUP BY solution.
To get the number of rows for a query do:
SELECT COUNT(*) as RowCount FROM (--insert other query here--) s
In you example:
SELECT COUNT(*) as RowCount FROM (SELECT a.from_uid
FROM assignment a
INNER JOIN curriculum_topics_assets c ON a.nid = c.asset
WHERE a.to_uid = 13
AND a.status = 1
GROUP BY a.from_uid, a.to_uid, a.nid
) s
Note that I the dropped the stuff that has no effect on the number of rows to make the query run slightly faster.
You should use COUNT(*) instead of count(description). Look at: http://www.mysqlperformanceblog.com/2007/04/10/count-vs-countcol/
Related
I am trying to return the price of the most recent record grouped by ItemNum and FeeSched, Customer can be eliminated. I am having trouble understanding how I can do that reasonably.
The issue is that I am joining about 5 tables containing hundreds of thousands of rows to end up with this result set. The initial query takes about a minute to run, and there has been some trouble with timeout errors in the past. Since this will run on a client's workstation, it may run even slower, and I have no access to modify server settings to increase memory / timeouts.
Here is my data:
Customer Price ItemNum FeeSched Date
5 70.75 01202 12 12-06-2017
5 70.80 01202 12 06-07-2016
5 70.80 01202 12 07-21-2017
5 70.80 01202 12 10-26-2016
5 82.63 02144 61 12-06-2017
5 84.46 02144 61 06-07-2016
5 84.46 02144 61 07-21-2017
5 84.46 02144 61 10-26-2016
I don't have access to create temporary tables, or views and there is no such thing as a #variable in C-tree, but in most ways it acts like MySql. I wanted to use something like GROUP BY ItemNum, FeeSched and select MAX(Date). The issue is that unless I put Price into the GROUP BY I get an error.
I could run the query again only selecting ItemNum, FeeSched, Date and then doing an INNER JOIN, but with the query taking a minute to run each time, it seems there is a better way that maybe I don't know.
Here is my query I am running, it isn't really that complicated of a query other than the amount of data it is processing. Final results are about 50,000 rows. I can't share much about the database structure as it is covered under an NDA.
SELECT DISTINCT
CustomerNum,
paid as Price,
ItemNum,
n.pdate as newest
from admin.fullproclog as f
INNER JOIN (
SELECT
id,
itemId,
MAX(TO_CHAR(pdate, 'MM-DD-YYYY')) as pdate
from admin.fullproclog
WHERE pdate > timestampadd(sql_tsi_year, -3, NOW())
group by id, itemId
) as n ON n.id = f.id AND n.itemId = f.itemId AND n.pdate = f.pdate
LEFT join (SELECT itemId AS linkid, ItemNum FROM admin.itemlist) AS codes ON codes.linkid = f.itemId AND ItemNum >0
INNER join (SELECT DISTINCT parent_id,
MAX(ins1.feesched) as CustomerNum
FROM admin.customers AS p
left join admin.feeschedule AS ins1
ON ins1.feescheduleid = p.primfeescheduleid
left join admin.group AS c1
ON c1.insid = ins1.feesched
WHERE status =1
GROUP BY parent_id)
AS ip ON ip.parent_id = f.parent_id
WHERE CustomerNum >0 AND ItemNum >0
UNION ALL
SELECT DISTINCT
CustomerNum,
secpaid as Price,
ItemNum,
n.pdate as newest
from admin.fullproclog as f
INNER JOIN (
SELECT
id,
itemId,
MAX(TO_CHAR(pdate, 'MM-DD-YYYY')) as pdate
from admin.fullproclog
WHERE pdate > timestampadd(sql_tsi_year, -3, NOW())
group by id, itemId
) as n ON n.id = f.id AND n.itemId = f.itemId AND n.pdate = f.pdate
LEFT join (SELECT itemId AS linkid, ItemNum FROM admin.itemlist) AS codes ON codes.linkid = f.itemId AND ItemNum >0
INNER join (SELECT DISTINCT parent_id,
MAX(ins1.feesched) as CustomerNum
FROM admin.customers AS p
left join admin.feeschedule AS ins1
ON ins1.feescheduleid = p.secfeescheduleid
left join admin.group AS c1
ON c1.insid = ins1.feesched
WHERE status =1
GROUP BY parent_id)
AS ip ON ip.parent_id = f.parent_id
WHERE CustomerNum >0 AND ItemNum >0
I feel it quite simple when I'd read the first three paragraphs, but I get a little confused when I've read the whole question.
Whatever you have done to get the data posted above, once you've got the data like that it's easy to retrive "the most recent record grouped by ItemNum and FeeSched".
How to:
Firstly, sort the whole result set by Date DESC.
Secondly, select fields you need from the sorted result set and group by ItemNum, FeeSched without any aggregation methods.
So, the query might be something like this:
SELECT t.Price, t.ItemNum, t.FeeSched, t.Date
FROM (SELECT * FROM table ORDER BY Date DESC) AS t
GROUP BY t.ItemNum, t.FeeSched;
How it works:
When your data is grouped and you select rows without aggregation methods, it will only return you the first row of each group. As you have sorted all rows before grouping, so the first row would exactly be "the most recent record".
Contact me if you got any problems or errors with this approach.
You can also try like this:
Select Price, ItemNum, FeeSched, Date from table where Date IN (Select MAX(Date) from table group by ItemNum, FeeSched,Customer);
Internal sql query return maximum date group by ItemNum and FeeSched and IN statement fetch only the records with maximum date.
I have an almost complex query like this:
SELECT qa.id,
qa.subject,
qa.category cat,
qa.keywords tags,
qa.body_html,
qa.amount,
qa.visibility,
qa.date_time,
COALESCE(u.reputation, 'N') reputation,
COALESCE(Concat(u.user_fname, ' ', u.user_lname), 'unknown') NAME,
COALESCE(u.avatar, 'anonymous.png') avatar,
(
SELECT COALESCE(Sum(vv.value),0)
FROM votes vv
WHERE qa.id = vv.post_id
AND 15 = vv.table_code) AS total_votes,
(
SELECT COALESCE(Sum(vt.total_viewed),0)
FROM viewed_total vt
WHERE qa.id = vt.post_id
AND 15 = vt.table_code limit 1) AS total_viewed
FROM qanda qa
LEFT JOIN users u
ON qa.author_id = u.id
AND qa.visibility = 1
WHERE qa.type = 0 $query_where
ORDER BY $query_order
LIMIT :j, 11;
Noted that $query_where variable contains some other conditions which will be created dynamically. Anyway, as you see, maximum it returns 10 posts.
Currently, to count total matched rows, I use another query like this:
SELECT COUNT(amount) paid_qs,
COUNT(*) all_qs
FROM qanda qa
WHERE type = 0 $query_where
I guess there is some waste processing. I mean two separated queries (with complex conditions on the where clause) will be too much.
Is there any approach to use one query instead of them?
You can query the found rows after the query with the FOUND_ROWS() function.
Reference: MySQL Reference Manual
You have to include the SELECT SQL_CALC_FOUND_ROWS ... clause into your query.
My
select distinct c.*
from kuponbahis c
join bahis b on b.sonuc = c.secim and b.ID=c.bahis AND c.durum=0
Query is giving the result as;
How can I get the count of results respect to their "kupon" field.
Expected result;
32, 3
33, 2
Thank you.
Group data by kupon and use count function to get the count of particular kupon
select c.kupon,count(*) as count
from kuponbahis c
join bahis b on b.sonuc = c.secim and b.ID=c.bahis AND c.durum=0
group by c.kupon
You need use group by:
select kupon, count(c.id)
from kuponbahis c
join bahis b on b.sonuc = c.secim and b.ID=c.bahis AND c.durum=0
group by 1
Also your origin query looks strange. You use JOIN (wich means INNER JOIN) and don't select any fields from joined table. In this case you can get zero results if your second table has no records to be joined. Maybe you should just remove JOIN statement?
If I understand you requirement correctly, you want to count the number of bahis, but only include rows that has bahis = 24. If so, you can use COUNT and filter the results in the HAVING clause
select c.kupon, count(*) as count
from kuponbahis c
join bahis b
on b.sonuc = c.secim
and b.ID = c.bahis
where
c.durum = 0
group by c.kupon
having count(case when c.bahis = 24 then 1 end) > 0
Here's my query:
SELECT a.product_title, b.product_title FROM products a, products b
WHERE b.color_id = a.color_id
AND b.price_id = a.price_id
AND b.size_id = a.size_id
AND a.id = 1
AND ??? (SELECT * FROM products LIMIT ???);
I'm trying to perform a sub query if the results of the first query is less than 10, how would I do this? Is it possible to count the rows the query gets out in the same query without performing another query?
Also is it possible to set the LIMIT to be what is required, ie. the first query gets 6 rows, I then need the limit to be 4 - to make up 10 all together.
I Really don't understand your question well,
anyway you can use variables ,
Example:
Set ACount = (select count(a.id) from products a where ...=...);
SELECT a.product_title, b.product_title FROM products a, products b
WHERE b.color_id = a.color_id
AND b.price_id = a.price_id
AND b.size_id = a.size_id
AND a.id = 1
AND if(#ACount<10, "Your where statement here",0);
You can do this using "UNION".
If you don't care about performance and just want to save one query, you can always UNION an second query and get the top 10 rows from the combined result:
SELECT * FROM (
SELECT a.product_title, b.product_title , 0 as Rank
FROM products a, products b
WHERE b.color_id = a.color_id
AND b.price_id = a.price_id
AND b.size_id = a.size_id
AND a.id = 1
LIMIT 10
UNION
SELECT product_title, '', Rank
FROM products
WHERE (your condition)
LIMIT 20
) E
ORDER BY Rank
LIMIT 10
Since the extra results from the second query will have higher rank, if you already have 10 records in the first query, there will be dropped by the limit.
Since Union will remove duplicates so you need add enough results to make sure you get at least 10.
The above code is to show you the concept and you need adjust it to suit your needs.
I have two tables in my MySQL database: allele and locus. I want to know for a given locus how many alleles there are and of those how many have the status Tentative. I currently have the following query with subquery:
SELECT COUNT(*) as alleleCount,
(SELECT COUNT(*)
FROM allele
INNER JOIN locus ON allele.LocusID = locus.PrimKey
WHERE Status = 'Tentative'
AND locus.ID = 762
) as newAlleleCount
FROM allele
INNER JOIN locus ON allele.LocusID = locus.PrimKey
WHERE locus.ID = 762
but I feel there must be a better way to write this query.
You can use SUM() using sum with condition will result in a boolean 1 or 0 so it will give you the count for your conditions
SELECT locus.ID,COUNT(*) `all_alleles_per_locus`,
SUM(Status = 'Tentative') `tentative_alleles_762`
FROM allele
INNER JOIN locus ON allele.LocusID = locus.PrimKey
GROUP BY locus.ID
One way would be to group the locus by its statuses and fetch each status's respective count; using the WITH ROLLUP modifier will add a NULL status at the end representing the total:
SELECT status, COUNT(*)
FROM allele JOIN locus ON locus.PrimKey = allele.LocusID
WHERE locus.ID = 762
GROUP BY status WITH ROLLUP
If you absolutely do not want a list of all statuses, you can instead GROUP BY status = 'Tentative' (optionally WITH ROLLUP if desired)—but it will not be sargable.