well, I want to get the best selling product, but when I want to get them. it just return the best selling product, but not idventa,idproduct,and description. well return the values but they are wrong values which they belong to other one. I need someone help me to correct me statement on sql because I want to return the right values like: idventa: 7 - idproducto: 10 , descripcion: IPHONE 4S, best_selling_product: 5000, and not the other values which they are not belong to the sentence
SELECT
idventa,idproducto,descripcion,MAX(venta_detalle.cantidad) AS best_selling_product
FROM venta_detalle
INNER JOIN producto
ON venta_detalle.idproducto = producto.id
Without knowing your table structures, it's a little difficult to guess what you're looking for. Sometimes you can get away with adding a group by clause assuming distinct values exist for that field.
Other times you need to join the table back to itself using aggregation in a subquery:
select
p.idproducto,
p.descripcion,
vd.idventa,
vd.cantidad
from producto p
join venta_detalle vd on vd.idproducto = p.id
join (select idproducto, max(cantidad) best_selling_product
from venta_detalle
group by idproducto) vd2 on vd.idproducto = vd2.idproducto and
vd.cantidad = vd2.best_selling_product
Although max() will return the highest number and without a group by it will also collapse the resultset into a single record, however, there is no guarantee that the other fields will come from the same record as the max. I suggest a simple order by and limit combo to get the record with the highest value:
SELECT
idventa,idproducto,descripcion, venta_detalle.cantidad AS best_selling_product
FROM venta_detalle
INNER JOIN producto
ON venta_detalle.idproducto = producto.id
ORDER BY venta_detalle.cantidad DESC
LIMIT 1
Related
I've got a problem with MySQL select statement.
I have a table with different Department and statuses, there are 4 statuses for every department, but for each month there are not always every single status but I would like to show it in the analytics graph that there is '0'.
I have a problem with select statement that it shows only existing statuses ( of course :D ).
Is it possible to create temporary table with all of the Departments , Statuses and amount of statuses as 0, then update it by values from other select?
Select statement and screen how it looks in perfect situation, and how it looks in bad situation :
SELECT utd.Departament,uts.statusDef as statusoforder,Count(uts.statusDef) as Ilosc_Statusow
FROM ur_tasks_details utd
INNER JOIN ur_tasks_status uts on utd.StatusOfOrder = uts.statusNR
WHERE month = 'Sierpien'
GROUP BY uts.statusDef,utd.Departament
Perfect scenario, now bad scenario :
I've tried with "union" statements but i don't know if there is a possibility to take only "the highest value" for every department.
example :
I've also heard about
With CTE tables, but I don't really get how to use it. Would love to get some tips on it!
Thanks for your help.
Use a cross join to generate the rows you want. Then use a left join and aggregation to bring in the data:
select d.Departament, uts.statusDef as statusoforder,
Count(uts.statusDef) as Ilosc_Statusow
from (select distinct utd.Departament
from ur_tasks_details utd
) d cross join
ur_tasks_status uts left join
ur_tasks_details utd
on utd.Departament = d.Departament and
utd.StatusOfOrder = uts.statusNR and
utd.month = 'Sierpien'
group by uts.statusDef, d.Departament;
The first subquery should be your source of all the departments.
I also suspect that month is in the details table, so that should be part of the on clause.
I hava a problem with distinct In every row by id I have 100 results.
I must show results for hearrate for player_id = 1, but it's only show about 250 results. It must be about 400
SELECT city.player_id, city.team_id, country.gender, account.first_name,
account.last_name,
city.position,player.status,GROUP_CONCAT(DISTINCT(playing))
FROM account
JOIN player
ON account.id = player.account_id JOIN city
ON player.id = city.player_id JOIN player_activity
ON player.id = player_activity.player_id JOIN team
ON city.team_id = country.id
GROUP BY player.id;
Any idea why is this doing?
You are only grouping by 1 of the columns that is not being aggregated., MySQL lets you do this but it produces inconsistent results
Try:
select city.player_id, city.team_id, country.gender, account.first_name,
account.last_name,
city.position,player.status,GROUP_CONCAT(DISTINCT(playing))
FROM account
JOIN player
ON account.id = player.account_id JOIN city
ON player.id = city.player_id JOIN player_activity
ON player.id = player_activity.player_id JOIN team
ON city.team_id = country.id
GROUP BY city.player_id, city.team_id, country.gender, account.first_name,
account.last_name,
city.position,player.status
;
Logically, the information you are asking the SQL to give you doesn't make any sense. Your query is asking SQL to return an individual record per player.id, yet you are also specifying that you would like to see several other columns displayed with this information.
How would you expect SQL to display to you a list of rows for (teamId, gender, etc..) that all have multiple rows in the database, when each of their player.id's was lumped into a single result (row)?
In essence, the query you are attempting to execute is invalid for this reason, and SQL is behaving weird/throwing errors because of this. Assuming that you can't aggregate fields like teamId and gender, I think you are a bit confused on what you are wanting SQL to do for you. What you really are wanting is SQL to ORDER BY, not GROUP BY, because you would like to see your results categorized by player.id rather than lumped into it. If you change your "GROUP BY" to an "ORDER BY", I'm betting you will see the results you are asking for. Hope this helps.
I am trying to list all of the stores that sell products that contain specific guitar parts for a guitar rig.
I have a guitarRig database. Guitar rigs have parts (I.e. amplifier, cabinet, microphone, guitarType, guitarStringType, patchCord, effectsPedal) which come from products, which are purchased from stores.
Products are purchased for a price as dictated by my PurchaseInformation table.
Here are my tables:
Table Part:
name
guitarRig references GuitarRig(name)
product references Product(name)
Table Product:
name
part references Part(name)
barcodeNumber
Table PurchaseInformation:
price
product references Product(name)
purchasedFrom references Store(name)
Table Store:
name
storeLocation
So far what I have is this:
SELECT p.name AS Part, prod.name AS Product, sto.name AS Store
FROM Part p, ProductInformation prod, Store sto, PurchaseInfo purch
WHERE sto.storeNumber = purch.storeNumber
AND purch.product = prod.name
AND prod.Part = p.name
AND p.name =
(
SELECT name
FROM Part
WHERE name LIKE '%shielded%'
)
GROUP BY p.name;
The error I get is that it returns more than 1 row, however, this is what I want! I want to list the stores that sell products that contain the part I am searching for.
The quick fix is to replace the equality comparison operator ( = ) with the IN operator.
AND p.name IN
(
SELECT name ...
I say that's the quick fix, because that will fix the error, but this isn't the most efficient way to write the query. And it's not clear your query is going return the result set you specified or actually expect.
I strongly recommend you avoid the old-school comma join operator, and use the JOIN keyword instead.
Re-structuring your query into an equivalent query yields this:
SELECT p.name AS Part
, prod.name AS Product
, sto.name AS Store
FROM Part p
JOIN ProductInformation prod
ON prod.Part = p.name
JOIN PurchaseInfo purch
ON purch.product = prod.name
JOIN Store sto
ON sto.storeNumber = purch.storeNumber
WHERE p.name IN
(
SELECT name
FROM Part
WHERE name LIKE '%shielded%'
)
GROUP BY p.name;
Some notes. The GROUP BY clause is going to collapse all of the joined rows into a single row for each distinct part name. That is, you are only going to get one row back for each part name.
It doesn't sound like that's what you want. I recommend you remove that GROUP BY, and add an ORDER BY, at least until you figure out what resultset you are getting, and if that's the rows you want to return.
Secondly, using the IN (subquery) isn't the most efficient approach. If p.name matches a value returned by that subquery, since p is a reference to the same Part table, this:
WHERE p.name IN
(
SELECT name
FROM Part
WHERE name LIKE '%shielded%'
)
is really just a more complicated way of saying this:
WHERE p.name LIKE '%shielded%'
I think you really want something more like this:
SELECT p.name AS Part
, prod.name AS Product
, sto.name AS Store
FROM Part p
JOIN ProductInformation prod
ON prod.Part = p.name
JOIN PurchaseInfo purch
ON purch.product = prod.name
JOIN Store sto
ON sto.storeNumber = purch.storeNumber
WHERE p.name LIKE '%shielded%'
ORDER BY p.name, prod.name, sto.name
That's going to return all rows from Part that include the string 'shielded' somewhere in the name.
We're going to match those rows to all rows in ProductInformation that match that part. (Note that with the inner join, if a Part doesn't have at least one matching row in ProductInformation, that row from Part will not be returned. It will only return rows that find at least one "matching" row in ProductionInformation.
Similarly, we join to matching rows in PurchaseInfo, and then to Store. Again, if there's not matching row from at least one Store, we won't get those rows back. This query is only going to return rows for Parts that are related to at least on Store. We won't get back any Part that's not in a Store.
The rows can be returned in any order, so to make the result set deterministic, we can add an ORDER BY clause. It's not required, it doesn't influence the rows returned, it only affects the sequence the rows that get returned.
I have a set of tables and I am trying to get the two counts by state to display. It's proving to be a little tricky partly because some results will have a count of 0. I'm not sure how to deal with those at the moment.
First I'll show my table structure and then I'll explain what counts I'm trying to get. I'm thinking its probably something simple, but I'm a little rusty on sql queries.
Here is how my tables are setup. I have one primary table that I'm using to join the other tables too.
t1 (primary table)
ID, qrtID, sdID, published
t2
qID, qTypes, qSlug
t3
stateID, stateName, stateAbbr
The values link like this. t1.qrtID = t2.qID, t1.sdID = t3.stateID.
The qSlug values has 2 possible values (past and present), so i want to get the counts based on those groups.
What I want to end up with are columns for stateName, qSlug_count1, and qSlug_count2. If there is a count of "0", i want to display "0".
So for now this is what i got.
SELECT * FROM
(SELECT sdID, COUNT(qrtID) AS past_count FROM t1 WHERE qrtID = "1" GROUP BY sdID) c1
LEFT JOIN
(SELECT sdID, COUNT(qrtID) AS pres_count FROM t1 WHERE qrtID = "2" GROUP BY sdID) c2
ON c1.sdID = c2.sdID
The results from this query are close to what I need, but i am missing some data. I need to get the stateName, stateAbbr, and also if there is a count of 0, show a 0 in the column. So all states should be respresented in the results.
So, the question is how can i modify the query I have above to add in the additional tables and join them to correct values AND also be able to show zero values if there are no records that match?
Just use conditional aggregation in a single query:
SELECT sdID,
sum(qrtID = "1") AS past_count
sum(qrtID = "2") AS pres_count
FROM t1
GROUP BY sdID;
Your query is missing rows because some sdIDs have only 1's and others have only 2's. You might want to add:
where qrtID in ("1", "2")
if you don't want rows where two 0s could appear.
I have three tables that are structured like this:
http://i41.tinypic.com/2bt9aq.png
What I am trying to do is retrieve the joke id, title, and average rating of all jokes in a certain category and order them alphabetically. I have this query:
$result = mysql_query("
SELECT jokedata.id AS joke_id,
jokedata.joketitle AS joke_title,
SUM(ratings.rating) / COUNT(ratings.rating) AS average
FROM jokedata
INNER JOIN ratings ON ratings.content_type = 'joke' AND ratings.relative_id = jokedata.id
WHERE jokecategory = '$cur_category'
GROUP BY jokedata.id
ORDER BY jokedata.joketitle
LIMIT $offset, $jokes_per_page
");
However it is not selecting any jokes.
What is wrong with that query? Thankyou.
First, you probably want to use AVG() instead of SUM()/COUNT().
Your problem is the inner join - if no ratings where submitted for a joke then that joke would not be returned as only jokes with a rating value match the inner join.
I would recommend using a left join instead, or even a sub-select. While I normally prefer JOINs as they are usually faster, I would have tried something like this:
SELECT id AS joke_id,
joketitle AS joke_title,
(
SELECT AVG(rating) AS avgrating FROM ratings
WHERE content_type = 'joke' AND relative_id = joke_id
GROUP BY relative_id
) AS average
FROM jokedata
WHERE jokecategory = '$cur_category'
GROUP BY id
ORDER BY joketitle
LIMIT $offset, $jokes_per_page
An inner join will not return a row if one of the joins cannot be fulfilled. So odds are good that the criteria ratings.relative_id = jokedata.id is causing the query to return 0 jokes. Try replacing the INNER JOIN with LEFT JOIN and you'll see how many of the jokedata's rows don't have matching id's in ratings.relative_id.
I would first narrow down the problem by taking out everything except the join and seeing what the result is:
SELECT *
FROM jokedata
INNER JOIN ratings ON ratings.content_type = 'joke' AND ratings.relative_id = jokedata.id
If this gives you results, I would then add back in the WHERE criteria. Do this step by step, and whenever you get a query where you have no rows returned, then look at the previous set of results, and think about what is happening when you add the additional criteria. Being able to see this "intermediate" set of results will help you identify and understand the problem.
Continue adding back to the query piece-wise until you start getting no results, at least then you've narrowed down to what aspect of the query is causing the problem.