not getting proper output in Group by Clause - mysql

I have been trying the following query using group by and inner join clause in asp.net:
SELECT tblVendorItem.Name AS Product,
tblEventItem.Quantity * tblEventItem.Price AS Sale
FROM
tblEventService
INNER JOIN tblEventItem ON
tblEventService.EventServiceID = tblEventItem.EventServiceID
INNER JOIN tblVendorItem ON
tblVendorItem.VendorItemID = tblEventItem.VendorItemID
WHERE
(tblEventService.VendorID = 2)
GROUP BY
tblVendorItem.Name, tblEventItem.Quantity, tblEventItem.Price
On executing this, what I get is:
What I really want is, Product should be not repeated and the total sales should come!
For eg: Mercedes 75
Can any one help me out?
I am attaching the database also:

INNER JOIN tblEventItem ON
tblEventService.EventServiceID = tblEventItem.EventServiceID
GROUP BY
tblVendorItem.Name, tblEventItem.Quantity, tblEventItem.Price
In the group by clause, remove tblEventItem.Quantity, tblEventItem.Price. Hence your query should be changed in two places.
First, SUM(price*quantity) and second:
GROUP BY
tblVendorItem.Name
The reason is this:
Group By X means put all those with the same value for X in the one group.
Group By X, Y means put all those with the same values for both X and Y in the one group.
Group By X means put all those with the same value for X in the one group.
Group By X, Y, Z means put all those with the same values for both X ,Y and Z in the one group.
I hope this helps.Using group by on multiple columns
Kudos! :)

Related

I was wondering if anyone knew how to find the min value and a max value and find the timeframe between them?

im working with a movie database I made and I wanted to make a select query that would separately select the the movie with the highest revenue and the movie with the lowest value and find the timeframe between them
i've tried to use the min and max functions to try to separately select the lowest and the highest movies and tried to use datediff() to try and the timeframe between them. my code is below
SELECT titles.title, min(financial_info.revenue),max(financial_info.revenue),
DATEDIFF(year, date(min(financial_info.revenue), date(max(financial.revenue)))
production_company.release_date
from titles
left join financial_info on titles.id = financial_info.id
left join production_company on
titles.imdb_id = production_company.imdb_id
I had aggregation error and a syntax error
The general format for this kind of query would be:
SELECT stuff
, maxB.Y - minB.Y -- Or, in this case DATEDIFF instead of minus
FROM (SELECT MIN(x) AS minX, MAX(x) AS maxX FROM a) AS minMax
INNER JOIN a AS minA ON minMax.minX = minA.X
INNER JOIN a AS maxA ON minMax.maxX = maxA.X
INNER JOIN b AS minB ON minA.b_id = minB.b_id
INNER JOIN b AS maxB ON maxA.b_id = maxB.b_id
;
You can end up with more than one result if there are multiple entries with the same revenue amount. (2 at min revenue and 3 at max revenue would yield 6 results).

MySQL sum case value equals max value of that group

I'm trying to solve this query to return the total count of items in a group and the total of items in that group which value equals the max value of one field of that group and also which is the max(value).
So far:
SELECT
limid, COUNT(*), SUM(CASE WHEN cotavertical=MAX(cotavertical) THEN 1 ELSE 0 END), MAX(cotavertical)
FROM limites
LEFT JOIN tbparentchild ON parent=limid
LEFT JOIN tbspatialbi ON child=rgi
WHERE limtipo=4 AND x=1
GROUP BY limid
So far MySQL returns
"Invalid use of group function."
Is it too complex to solve in MySQL only? Better to use algorithm?
You are trying to use the max value for each group in an aggregate function (SUM) before the aggregation has finished, and hence it is not available. The query below uses the strategy of joining a subquery which contains the max value of cotavertical for each limid group. In this case, the max value per group which you want to use will now be available from another source, and you can sum using it.
SELECT l.limid,
COUNT(*),
SUM(CASE WHEN cotavertical = t.cotamax THEN 1 ELSE 0 END),
MAX(cotavertical)
FROM limites l
LEFT JOIN tbparentchild pc
ON pc.parent = l.limid
LEFT JOIN tbspatialbi s
ON pc.child = s.rgi
LEFT JOIN
(
SELECT limid, MAX(cotavertical) AS cotamax
FROM limites
LEFT JOIN tbparentchild
ON parent = limid
LEFT JOIN tbspatialbi
ON child = rgi
WHERE limtipo = 4 AND x = 1
GROUP BY limid
) t
ON l.limid = t.limid
WHERE limtipo = 4 AND l.x = 1
GROUP BY l.limid
Another option for solving your problem would be to use a subquery directly in the CASE statement. But, given the size and number of joins in your original query, this would be way uglier than the query above. MySQL does not support common table expressions, which would have helped with both these solutions.

COUNT evaluate to zero if no matching records

Take the following:
SELECT
Count(a.record_id) AS newrecruits
,a.studyrecord_id
FROM
visits AS a
INNER JOIN
(
SELECT
record_id
, MAX(modtime) AS latest
FROM
visits
GROUP BY
record_id
) AS b
ON (a.record_id = b.record_id) AND (a.modtime = b.latest)
WHERE (((a.visit_type_id)=1))
GROUP BY a.studyrecord_id;
I want to amend the COUNT part to display a zero if there are no records since I assume COUNT will evaluate to Null.
I have tried the following but still get no results:
IIF(ISNULL(COUNT(a.record_id)),0,COUNT(a.record_id)) AS newrecruits
Is this an issue because the join is on record_id? I tried changing the INNER to LEFT but also received no results.
Q
How do I get the above to evaluate to zero if there are no records matching the criteria?
Edit:
To give a little detail to the reasoning.
The studies table contains a field called 'original_recruits' based on activity before use of the database.
The visits tables tracks new_recruits (Count of records for each study).
I combine these in another query (original_recruits + new_recruits)- If there have been no new recruits I still need to display the original_recruits so if there are no records I need it to evalulate to zero instead of null so the final sum still works.
It seems like you want to count records by StudyRecords.
If you need a count of zero when you have no records, you need to join to a table named StudyRecords.
Did you have one? Else this is a nonsense to ask for rows when you don't have rows!
Let's suppose the StudyRecords exists, then the query should look like something like this :
SELECT
Count(a.record_id) AS newrecruits -- a.record_id will be null if there is zero count for a studyrecord, else will contain the id
sr.Id
FROM
visits AS a
INNER JOIN
(
SELECT
record_id
, MAX(modtime) AS latest
FROM
visits
GROUP BY
record_id
) AS b
ON (a.record_id = b.record_id) AND (a.modtime = b.latest)
LEFT OUTER JOIN studyrecord sr
ON sr.Id = a.studyrecord_id
WHERE a.visit_type_id = 1
GROUP BY sr.Id
I solved the problem by amending the final query where I display the result of combining the original and new recruits to include the IIF there.
SELECT
a.*
, IIF(IsNull([totalrecruits]),consents,totalrecruits)/a.target AS prog
, IIf(IsNull([totalrecruits]),consents,totalrecruits) AS trecruits
FROM
q_latest_studies AS a
LEFT JOIN q_totalrecruitment AS b
ON a.studyrecord_id=b.studyrecord_id
;

Mysql query that includes TWO sums from columns in other tables

Got a query running one sum from a different table, which works perfectly (and obtained from this forum as well):
SELECT
R.REP_ID as repid, R.REP_DESBREV as repdesc,
IFNULL(SUM(RD.REPDATA_CANT), 0) as cant
FROM
REPUESTOS R
LEFT JOIN
REP_DATA RD, ON RD.REPDATA_REPID = R.REP_ID
GROUP BY
RD.REPDATA_REPID
Now, the thing is that I'd like to add an extra column that obtains the total inventory (something like
IFNULL(SUM(I.INV_CANT), 0) as inv)
FROM table INVENTARIO I
WHERE I.INV_REPID = R.REP_ID
This value can be obtained by means of a JOIN, in the exact same way we got the first statement that works, but I have not found the way to include BOTH SUMS in just one query.
Any ideas? THANKS!
Try this query example
select
t1.id,
ifnull(sum(t1.my_column),0) as Sum1,
ifnull(other.sum,0) as Sum2
from table as t1
left join (select id , sum(other_table_column) from other_table group by id) as other
on t1.id = other.id
group by t1.id
I just implemented the following statement:
SELECT
R.REP_PARNUM as parnum,
R.REP_ID as repid,
R.REP_DESBREV as repdesc,
IFNULL(SUM(RD.REPDATA_CANT),0) as cant,
IFNULL(SUM(I.INV_CANT),0) as intt
FROM REPUESTOS R
LEFT JOIN REP_DATA RD ON RD.REPDATA_REPID = R.REP_ID
LEFT JOIN INVENTARIO I ON I.INV_REPID = R.REP_ID
GROUP BY R.REP_PARNUM
It actually runs, but the problem is that it's giving me some weird values. For example, some of the values in the first sum column (REPDATA_CANT) are shown with -3, i.e. if the real result is 20, it shows 17 and so on. In the second sum column (INV_CANT), it actually MULTIPLIES (in some rows, not all) the value by 3. Very weird behaviour, do you have an idea why?

Most efficient SQL, DISTINCT or WHERE...AND

Both of these work, but is there a better way to write this?
1.
SELECT asset_id,
asset.category_id,
x,
y
FROM asset
INNER JOIN map_category
ON map_category.category_id = asset.category_id
WHERE asset.map_id = 5
AND map_category.map_id = 5
2. (Added DISTINCT and removed last line)
SELECT DISTINCT asset_id,
asset.category_id,
x,
y
FROM asset
INNER JOIN map_category
ON map_category.category_id = asset.category_id
WHERE asset.map_id = 5
Without either DISTINCT or the last line AND map_cate..., I get 3 records. One for each:
map_category table
asset table
These two queries do completely different things. DISTINCT selects only unique asset_id rows and another query selects only rows where asset.map_id = 5.
The reason you have the same result is your data. On some other data you will have completely different results. So you can't compare efficiency.
since your foreign key consists of both the columns, you should join on both columns...
SELECT asset_id,
asset.category_id,
x,
y
FROM asset
INNER JOIN map_category
ON map_category.category_id = asset.category_id
AND asset.map_id = map_category.map_id