Hi I am joining the tables to return data but I want that data to be grouped by specific location and also count/sum the values that are related to that location
at the moment I can only retrieve the data but it does not sum/count the values of that location Here is my query
select brand_locations.locationName,campaign_stats.clicks,
campaign_stats.impressions,
campaign_stats.day,brand_locations.city,
click_actions.walkTo,click_actions.showMap,
click_actions.call,click_actions.coupon,driveTo,campaigns_details.state
from campaign_stats
inner join campaigns_details on campaign_stats.campaignId = campaigns_details.campaignId
inner join click_actions on click_actions.campaignId=campaign_stats.campaignId
inner join brand_locations on brand_locations.brandId = campaigns_details.brandId
where brand_locations.city = 'cape town'
The output is
bellville 58
water front 12
bellville 4
bellville 1
century city 2
century city 4
My goal is to have
bellville 63
water front 12
century city 6
Thanks
MySQL SUM() function retrieves the sum value of an expression which has undergone a grouping operation by GROUP BY clause. Have you tried this option?
select brand_locations.locationName,SUM(campaign_stats.clicks),
campaign_stats.impressions,
campaign_stats.day,brand_locations.city,
click_actions.walkTo,click_actions.showMap,
click_actions.call,click_actions.coupon,driveTo,campaigns_details.state
from campaign_stats
inner join campaigns_details on campaign_stats.campaignId = campaigns_details.campaignId
inner join click_actions on click_actions.campaignId=campaign_stats.campaignId
inner join brand_locations on brand_locations.brandId = campaigns_details.brandId
where brand_locations.city = 'cape town' group by brand_locations.locationName
Try this query. I have added a group by location name to the query and also used function sum to calcualate the total number of clicks.
select brand_locations.locationName,SUM(campaign_stats.clicks) as campaign_stats_cnt,
sum(campaign_stats.impressions) as impressions_cnt,
campaign_stats.day,brand_locations.city,
click_actions.walkTo,click_actions.showMap,
click_actions.call,click_actions.coupon,driveTo,campaigns_details.state
from campaign_stats
inner join campaigns_details on campaign_stats.campaignId = campaigns_details.campaignId
inner join click_actions on click_actions.campaignId=campaign_stats.campaignId
inner join brand_locations on brand_locations.brandId = campaigns_details.brandId
where brand_locations.city = 'cape town' group by brand_locations.locationName
You can use sum() to get the results you want from the result you are getting
SELECT title, SUM(count)
FROM (resultQuery)
GROUP BY title
NOTE: Replace title with the name of your first column, count with the name of your second column and resultQuery with they query you have above
And yes, this is the hacky sub-query way of doing it....
Related
I've got a query with avg results. In another table I have the results of that
avg result in text.
Right now this is my query:
select round(avg(breed_ratings.rating)) as result, breed_ratings.score_name, count(*) as total, breeds.name_en
from breed_ratings
inner join breeds on breeds.id = breed_ratings.breed_id
where breeds.id = 188
group by score_name, breeds.name_en
The rating_result table looks like this:
id
rating
result_text
How can I get the result_text in this query?
Please help me out.
--EDIT
I need to get the result from the image below in text.
So I have another table where this is stored I need to get the result_nl where it matches the rating:
Desired result (if rating is 5):
result: 5
score_name: ADULT_FRIENDLY
total: 117
name_en: American Staffordshire Terrier
result_nl: I am extremely dominant
I think you want to join the average to the first rating in rating_results where the average is bigger than the listed rating there. If so:
select br.*, rr.result_text
from (select round(avg(br.rating)) as result, br.score_name, count(*) as total, b.name_en
from breed_ratings br join
breeds b
on b.id = br.breed_id
where b.id = 188
group by br.score_name, b.name_en
) br left join
(select rr.*, lead(rr.rating) over (order by rr.rating) as next_rating
from rating_result rr
) rr
on br.result >= rr.rating and
(br.result < rr.next_rating or rr.next_rating is null)
My query does return the lowest price from the two columns (price_base, price_special) but it is not returning the correct store_id that corresponds to the lowest price found.
My Query:
SELECT grocery_item.id, grocery_item.category,
grocery_category.name AS cat, grocery_item.name AS itemName,
MIN( if( grocery_price.price_special>0,
grocery_price.price_base)) AS price,
grocery_price.store_id,
grocery_store.name AS storeName
FROM grocery_item
LEFT JOIN grocery_category ON
grocery_category.id=grocery_item.category
LEFT JOIN grocery_price
ON grocery_price.item_id = grocery_item.id
LEFT JOIN grocery_store
ON grocery_store.id=grocery_price.store_id
WHERE grocery_price.selection='no'
AND buy='yes'
GROUP BY grocery_price.item_id
ORDER BY store_id, grocery_item.category, grocery_item.name
Returns this:
ID category cat itemName price store_id storeName
92 3 Bread/Bakery Arnold Bread 2.14 1 Food Lion
But the grocery_price table holds this info:
item_id price_base price_special store_id
92 4.29 2.14 9
92 3.99 0.00 1
so the store_id I need to be returned is 9 (the storeName returned would NOT then be Food Lion)
EDIT: WORKING QUERY based on Uueerdo's comments (thank you!)
SELECT minP.item_id, gi.category, gc.name AS cat,
gi.name as itemName, gp.store_id,
gs.name AS storeName, minP.price
FROM
(SELECT p.item_id, MIN(IF(p.price_special >0,
p.price_special,p.price_base)) AS price
FROM grocery_item AS i
INNER JOIN grocery_price AS p ON (i.id = p.item_id)
WHERE i.buy = 'yes'
GROUP BY p.item_id) AS minP
INNER JOIN grocery_item AS gi ON minP.item_id = gi.id
INNER JOIN grocery_category AS gc on gi.category = gc.id
LEFT JOIN grocery_price AS gp
ON minP.price = IF(gp.price_special > 0,
gp.price_special,gp.price_base)
AND gp.item_id = gi.id
INNER JOIN grocery_store AS gs ON gp.store_id = gs.id
GROUP BY gi.id
ORDER BY gs.id, gi.category,gi.name
The values returned for non-grouped, non-aggregated fields are an (effectively) random selection from the values encountered with the grouped fields' values. Most RDBMS do not even consider such a query valid, and even newer versions of MySQL default to disallowing such queries.
In cases like yours, where you need the non-grouped value(s) associated with the aggregate result (min in this case); the aggregating query must be converted into a subquery, that can be joined back to the aggregated tables to find the source row(s) that correspond to the aggregated value.
Edit: Basically, you need to look at the problem slightly differently. You're currently finding the lowest price for an item and a store that item is listed for; you need to find the lowest price for an item, and use that to find the store(s) that have the item at that price.
This gets you the lowest price for item's marked "buy":
SELECT p.item_id, MIN(IF(p.price_special > 0,p.price_special,p.price_base)) AS price
FROM grocery_item AS i
INNER JOIN grocery_price AS p ON (i.id = p.item_id)
WHERE i.buy = 'yes'
GROUP BY p.item_id
You can then take that to get the rest of the results:
SELECT minP.item_id
, gi.name
, gi.category, gc.category_name AS cat, gi.Name as itemName, gi.buy
, gp.store_id, gp.name AS storeName
, minP.price
FROM ([the query above]) AS minP
INNER JOIN grocery_item AS gi ON minP.item_id = gi.id
INNER JOIN grocery_category AS gc on gi.category = gc.grocery_category_id
/* Guessing on this join since grocery_category_id
was not qualified with it's table name */
INNER JOIN grocery_price AS gp
ON minP.price = IF(gp.price_special > 0,gp.price_special,gp.price_base)
/* Alternatively: ON minP.price IN (gp.price_special, gp.price_base)
... though this could cause false positives if the minP.price is 0
from one store's base price being "free"
*/
INNER JOIN grocery_store AS gs ON gp.store_id = gs.id
;
Here's the code:
SELECT tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, MAX(tblitemprice.dtmItemPasOf) AS Expr1,
tblitemprice.dblItemPAmount
FROM tblclassification INNER JOIN
tblitem ON tblclassification.strClasCode = tblitem.strItemClasCode INNER JOIN
tblitemprice ON tblitem.strItemCode = tblitemprice.strItemPItemCode INNER JOIN
tblitemunit ON tblitemprice.strItemPItemUnitCode = tblitemunit.strItemUnitCode INNER JOIN
tblvendor ON tblclassification.strClasCode = tblvendor.strVendClasCode AND tblitemprice.strItemPVendCode = tblvendor.strVendCode AND tblitem.deleted_at IS NULL
GROUP BY tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, tblitemprice.dblItemPAmount
And Here's the Result:
CODE NAME UNIT VENDOR DATE PRICE
ITEM101-Fudgee Bar-Piece-Imus Palengke 10/9/20165:03:32AM - 6.5
ITEM102-Yum Burger-Box-Jollibee Lumina Mall-10/9/2016 6:13:27 AM - 2500
ITEM102-Yum Burger-Piece-Jollibee Lumina Mall-10/9/2016 4:42:28 AM - 30
ITEM102-Yum Burger-Piece-Jollibee Lumina Mall-10/13/2016 12:37:31 PM- 35
ITEM102-Yum Burger Piece Jollibee Lumina Mall 10/14/2016 10:05:44 PM 40
What I want to happen is to fetch only the row with the latest price. Can someone help me please.
I want to fetch the Item101 and only the last row to ITEM102 since it is the latest.
If I understand correctly, you're looking for the last updated row price. It's easy to do so:
Order your data by their relevant timestamp in reversed order (ORDER BY <FIELD_NAME> DESC). From what I gather from your query and results, Expr1 is the latest date for a given price.
Only pick a single element (LIMIT 1). Since your data is already ordered in reverse chronological order, you're sure to pick the latest one.
The SQL for that would be
SELECT tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, MAX(tblitemprice.dtmItemPasOf) AS Expr1,
tblitemprice.dblItemPAmount
FROM tblclassification INNER JOIN
tblitem ON tblclassification.strClasCode = tblitem.strItemClasCode INNER JOIN
tblitemprice ON tblitem.strItemCode = tblitemprice.strItemPItemCode INNER JOIN
tblitemunit ON tblitemprice.strItemPItemUnitCode = tblitemunit.strItemUnitCode INNER JOIN
tblvendor ON tblclassification.strClasCode = tblvendor.strVendClasCode AND tblitemprice.strItemPVendCode = tblvendor.strVendCode AND tblitem.deleted_at IS NULL
GROUP BY tblitem.strItemCode, tblitem.strItemName, tblitemunit.strItemUnitName, tblvendor.strVendName, tblitemprice.dblItemPAmount
ORDER BY Expr1 DESC
LIMIT 1
Try it out !
Ok, what I'm trying to do is try and get unique values from one table that span 4 separate columns.
For example, I have this below query which works correctly on one of the columns..
SELECT
rest.cuisine1, c.name
FROM
specials
INNER JOIN restaurant AS rest ON specials.restaurantid=rest.id
INNER JOIN cuisine AS c ON rest.cuisine1=c.id
WHERE
dateend >= CURDATE()
AND
(specials.state='VIC' OR specials.state = 'ALL')
AND
specials.status = 1
AND
rest.status = 1
GROUP BY
c.id;
Now, rest.cuisine1 is one of the columns that contain the data. As expected this query returns unique values from that column only. The below being an example of what is returned:
12 Cafe
18 Asian
29 Coffee
There are 3 more columns in that table, those being:
rest.cuisine2
rest.cuisine3
rest.cuisine4
I could run the above query 4 times (one on each column) and THEN run the values through PHP to get only unique values from the 4 different result sets, however I was wanting to find out if I can get what I want all in the one query.
try this
SELECT
rest.cuisine1, c.name ,rest.cuisine2 , rest.cuisine3, rest.cuisine4
FROM
specials
INNER JOIN restaurant AS rest ON specials.restaurantid=rest.id
INNER JOIN cuisine AS c ON rest.cuisine1=c.id
INNER JOIN cuisine AS c2 ON rest.cuisine2=c2.id
INNER JOIN cuisine AS c3 ON rest.cuisine3=c3.id
INNER JOIN cuisine AS c4 ON rest.cuisine4=c4.id
WHERE
dateend >= CURDATE()
AND
(specials.state='VIC' OR specials.state = 'ALL')
AND
specials.status = 1
AND
rest.status = 1
GROUP BY
c.id;
This answer is based off of MahmoudGamal's answer he posted in a comment, which he deleted for some reason.
I used the below..
SELECT
c.id, c.name
FROM
specials
INNER JOIN restaurant AS rest ON specials.restaurantid=rest.id
INNER JOIN cuisine AS c ON c.id IN (rest.cuisine1, rest.cuisine2, rest.cuisine3, rest.cuisine4)
WHERE
dateend >= CURDATE()
AND
(specials.state='VIC' OR specials.state = 'ALL')
AND
specials.status = 1
AND
rest.status = 1
GROUP BY
c.id;
I have this query, where I am trying to get max age of a retail store seller(There's multiple towns), and show multiple if there's multiple people with the same (max)age. I am using Microsoft Access 2010. Here is the query:
SELECT Linnad.Linn, Myyjad.Nimi, Max(Myyjad.Vanus) As Vanus
FROM Linnad INNER JOIN Myyjad ON Linnad.LinnID = Myyjad.LinnID
GROUP BY Linnad.Linn, Myyjad.Nimi
ORDER BY Linnad.Linn;
The problem is, it seems to ignore the MAX, and just shows all of the values, and I can't remove the group by Myyjad.Nimi, because it gives me an error that aggregate function not included for Myyjad.Nimi.
And the output should be:
Town - Name - Max(Age)
Also, Linn = Town, Nimi = Name and the Vanus = Age.
I think this may be what your looking for:
SELECT L.Linn, M.Nimi, M.Vanus
FROM Linnad As L,
(
SELECT M2.LinnID, M2.Nimi, M2.Vanus
FROM Myyjad As M2
WHERE M2.Vanus = (SELECT Max(Z.Vanus) FROM Myyjad As Z WHERE Z.LinnID = M2.LinnID)
) As M
WHERE M.LinnID = L.LinnID
This performs a sub-select to get a list of the Linn ID's with all Nimi's showing the maximum Vanus, then we link this sub-select back to the Linnad table via the LinnID.
I think you want:
SELECT Linnad.Linn, Myyjad.Nimi, Myyjad.Vanus
FROM Linnad INNER JOIN Myyjad ON Linnad.LinnID = Myyjad.LinnID
WHERE DateValue(Myyjad.Vanus)
= (SELECT Max(DateValue(Myyjad.Vanus)) FROM Myyjad)
ORDER BY Linnad.Linn
Top N per group:
SELECT Linnad.Linn, Myyjad.Nimi, Myyjad.Vanus
FROM FROM Linnad INNER JOIN Myyjad ON Linnad.LinnID = Myyjad.LinnID
WHERE Myyjad.ID In (
SELECT Top 1 m.ID
FROM Myyjad m
WHERE m.LinnID=Linnad.ID
ORDER BY m.Vanus Desc, m.ID)
Grouping by Linn (town) and Nimi (name) tells the db engine to give you one row for each combination of town and name, and show you the maximum Vanus (age) for each of those combinations. And logically, that's not what you want. You want the name of each person whose age is the same as the maximum age in that town.
First verify you can retrieve the max age for each LinnID.
SELECT
LinnID,
Max(Vanus) As MaxOfVanus
FROM
Myyjad
GROUP BY LinnID;
If that works, you can save it as "qryTownAge", then use it in another query where you join it (on LinnID) with Linnad. That will allow you to retrieve the matching Linn.
SELECT l.LinnID, l.Linn, q.MaxOfVanus
FROM
Linnad AS l
INNER JOIN qryTownAge AS q
ON l.LinnID = q.LinnID
ORDER BY l.Linn;
If that works, save it as qryTownAge2. Then try this query.
SELECT q.Linn, q.MaxOfVanus, m.Nimi
FROM
qryTownAge2 AS q
INNER JOIN Myyjad AS m
ON (
m.LinnID = q.LinnID
AND m.Vanus = q.MaxOfVanus
)
ORDER BY q.Linn;
If that all works, you could create a single query which does it all. However, doing it step by step should help us pinpoint errors.