i need help with this query.. i keep stats for a First Person Shooter.
The data looks like this:
I've am this far with the query:
SELECT
a.name,p.killer as killer_id, ROUND(AVG(p.distance)) as average_distance,p.bambikill,
(Select count(killer)) as total_kills,
(Select count(bambikill) where bambikill = 1)as newbiekills
FROM
player_stats p
inner join account a on p.killer = a.uid
group by killer_id
The result of the
What i need to do next is get the deaths of the player 'killer' which woudl be in the victim column and count for all that player's deaths. Each time he's shown up tin the victim column.
Is this possible? I've tried a few combinations but can't seem to get it right. I'm not the best with MySQL queries.
One option to determine the number of times a killer has himself been killed is to use a subquery which aggregates over the victim column. Then LEFT JOIN your current query to this subquery. Note that LEFT JOIN is used to allow for the possibility that a killer never in fact gets killed. In this case, COALESCE would report zero for this stat.
SELECT t2.name,
t1.killer_id,
t1.average_distance,
t1.total_kills,
t1.newbiekills,
COALESCE(t3.numKills, 0) AS num_times_killed
FROM
(
SELECT p.killer AS killer_id,
ROUND(AVG(p.distance)) AS average_distance,
COUNT(*) AS total_kills,
SUM(p.bambikill) AS newbiekills
FROM player_stats p
GROUP BY p.killer
) t1
INNER JOIN account t2
ON t1.killer = t2.uid
LEFT JOIN
(
SELECT victim, COUNT(*) AS numKills
FROM player_stats
GROUP BY victim
) t3
ON t1.killer = t3.victim
GROUP BY t1.killer
Related
I have two tables - one is a list of addresses, and the other of attendance dates and EmployeeIDNumbers to identfy the engineer who attended. An engineer may have attended an address multiple times. I am trying to select the address name, and the most recent attendance date and corresponding engineerID
select s.sitename, max(sd.scheduleddate), sd.EngineerID
from sites as s
left join scheduled_dates as sd on sd.idsites = s.idsites
group by s.idsites
This code correctly pulls each address and the most recent 'Scheduled Date' but does not pull the correct corresponding engineer id. How do I get the engineerID from the same row as the max(scheduleddate)? Think this is something to do with the 'greatest-n-per-group' discussion, but I can't see how to implement that code with a query that already has a join
You can use a NOT EXISTS condition with a correlated subquery:
select s.sitename, sd.EngineerID, sd.scheduleddate
from sites as s
inner join scheduled_dates as sd on sd.idsites = s.idsites
where not exists (
select 1
from scheduled_dates sd1
where sd1.idsites = s.idsites
and sd1.scheduleddate > sd.scheduleddate
)
The condition ensures that there no other record exists in scheduled_dates for the current site with a date greater than the one on the record being selected.
Notes: I turned you LEFT JOIN to an INNER JOIN, since I believe that it better fit your use cases, feel free to revert this if needed.
In MySQL 8+, you can use window functions:
select s.sitename, sd.scheduleddate, sd.EngineerID
from sites s left join
(select sd.*,
row_number() over (partition by sd.idsites orer by sd.scheduleddate desc) as seqnum
from scheduled_dates sd
) sd
on sd.idsites = s.idsites and sd.seqnum = 1;
Note that this also keeps all sites (which appears to be your intention), even those that have not been visited.
I am attempting to create a subquery in Access but I am receiving an error stating that one record can be returned by this subquery. I am wanting to find the top 10 companies that have the most pets then I want to know the name of those pets. I have never created a subquery before so I am not sure where I am going wrong. Here is what I have:
SELECT TOP 10 dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
(SELECT dbo_tPet.Pet
FROM dbo_tPet)
FROM dbo_tPet INNER JOIN dbo_tGovenrnmentRegulatoryAgency ON
dbo_tPet.GovernmentRegulatoryAgencyID =
dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgencyID
GROUP BY dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.PetID) DESC;
Consider this solution, requiring a subquery in the WHERE IN () clause:
SELECT t1.GovernmentRegulatoryAgency, dbo_tPet.Pet,
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t1 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t1.GovernmentRegulatoryAgencyID
WHERE t1.GovernmentRegulatoryAgency IN
(SELECT TOP 10 t2.GovernmentRegulatoryAgency
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t2 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t2.GovernmentRegulatoryAgencyID
GROUP BY t2.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.Pet) DESC);
Table aliases are not needed but I include them for demonstration.
This should hopefully do it:
SELECT a.GovernmentRegulatoryAgency, t.NumOfPets
FROM dbo_tGovenrnmentRegulatoryAgency a
INNER JOIN (
SELECT TOP 10 p.GovernmentRegulatoryAgencyID, COUNT(p.PetID) AS NumOfPets
FROM dbo_tPet p
GROUP BY p.GovernmentRegulatoryAgencyID
ORDER BY COUNT(p.PetID) DESC
) t
ON a.GovernmentRegulatoryAgencyID = t.GovernmentRegulatoryAgencyID
In a nutshell, first get the nested query sorted, identifying what the relevant agencies are, then inner join back to the agency table to get the detail of the agencies so picked.
Everything in the following query results in one line for each invBlueprintTypes row with the correct information. But I'm trying to add something to it. See below the codeblock.
Select
blueprintType.typeID,
blueprintType.typeName Blueprint,
productType.typeID,
productType.typeName Item,
productType.portionSize,
blueprintType.basePrice * 0.9 As bpoPrice,
productGroup.groupName ItemGroup,
productCategory.categoryName ItemCategory,
blueprints.productionTime,
blueprints.techLevel,
blueprints.researchProductivityTime,
blueprints.researchMaterialTime,
blueprints.researchCopyTime,
blueprints.researchTechTime,
blueprints.productivityModifier,
blueprints.materialModifier,
blueprints.wasteFactor,
blueprints.maxProductionLimit,
blueprints.blueprintTypeID
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
So what I need to get in here is the following table with the columns below it so I can use the values timestamp and sort the entire result by profitHour
tablename: invBlueprintTypesPrices
columns: blueprintTypeID, timestamp, profitHour
I need this information with the following select in mind. Using a select to show my intention of the JOIN/in-query select or whatever that can do this.
SELECT * FROM invBlueprintTypesPrices
WHERE blueprintTypeID = blueprintType.typeID
ORDER BY timestamp DESC LIMIT 1
And I need the main row from table invBlueprintTypes to still show even if there is no result from the invBlueprintTypesPrices. The LIMIT 1 is because I want the newest row possible, but deleting the older data is not a option since history is needed.
If I've understood correctly I think I need a subquery select, but how to do that? I've tired adding the exact query that is above with a AS blueprintPrices after the query's closing ), but did not work with a error with the
WHERE blueprintTypeID = blueprintType.typeID
part being the focus of the error. I have no idea why. Anyone who can solve this?
You'll need to use a LEFT JOIN to check for NULL values in invBlueprintTypesPrices. To mimic the LIMIT 1 per TypeId, you can use the MAX() or to truly make sure you only return a single record, use a row number -- this depends on whether you can have multiple max time stamps for each type id. Assuming not, then this should be close:
Select
...
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Left Join (
SELECT MAX(TimeStamp) MaxTime, TypeId
FROM invBlueprintTypesPrices
GROUP BY TypeId
) blueprintTypePrice On blueprints.blueprintTypeID = blueprintTypePrice.typeID
Left Join invBlueprintTypesPrices blueprintTypePrices On
blueprintTypePrice.TypeId = blueprintTypePrices.TypeId AND
blueprintTypePrice.MaxTime = blueprintTypePrices.TimeStamp
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
Order By
blueprintTypePrices.profitHour
Assuming you might have the same max time stamp with 2 different records, replace the 2 left joins above with something similar to this getting the row number:
Left Join (
SELECT #rn:=IF(#prevTypeId=TypeId,#rn+1,1) rn,
TimeStamp,
TypeId,
profitHour,
#prevTypeId:=TypeId
FROM (SELECT *
FROM invBlueprintTypesPrices
ORDER BY TypeId, TimeStamp DESC) t
JOIN (SELECT #rn:=0) t2
) blueprintTypePrices On blueprints.blueprintTypeID = blueprintTypePrices.typeID AND blueprintTypePrices.rn=1
You don't say where you are putting the subquery. If in the select clause, then you have a problem because you are returning more than one value.
You can't put this into the from clause directly, because you have a correlated subquery (not allowed).
Instead, you can put it in like this:
from . . .
(select *
from invBLueprintTypesPrices ibptp
where ibtp.timestamp = (select ibptp2.timestamp
from invBLueprintTypesPrices ibptp2
where ibptp.blueprintTypeId = ibptp2.blueprintTypeId
order by timestamp desc
limit 1
)
) ibptp
on ibptp.blueprintTypeId = blueprintType.TypeID
This identifies the most recent records for all the blueprintTypeids in the subquery. It then joins in the one that matches.
I have a problem with a query which should do the following:
Get specific records and calculate some of their values for specific period of time
Calculate same values of these keywords for another period of time
This should happen into 1 query. I was able to write it but SUM() returns wrong value much higher than normal. I think that this is because of LEFT JOIN.
SELECT SQL_CALC_FOUND_ROWS table1.id, table1.KeywordId, table1.AccountName, table1.CampaignName, table1.AdGroupName, table1.Keyword, table1.MatchType, SUM(table1.Spend)/SUM(table1.Clicks) AS AverageCpc, SUM(table1.Impressions) AS Impressions, (SUM(table1.Clicks)*table1.revenue_price)/SUM(table1.Impressions) AS Ctr, SUM(table1.Impressions*table1.AveragePosition)/SUM(table1.Impressions) AS AveragePosition, SUM(table1.Clicks) AS Clicks, SUM(table1.Spend) AS Spend, SUM(table1.free_joins) AS FreeJoins, SUM(table1.paid_joins) AS PaidJoins, SUM(table1.paid_joins)*table1.revenue_price AS Revenue, (SUM(table1.paid_joins)*table1.revenue_price)-SUM(table1.Spend) AS Profit, (SUM(table1.paid_joins)*table1.revenue_price)/SUM(table1.Clicks) AS RevPerClick, table1.CurrentMaxCpc, SUM(table2.Impressions) AS Impressions_chg, SUM(table2.Clicks) AS Clicks_chg, SUM(table2.Impressions*table2.AveragePosition)/SUM(table2.Impressions) AS AveragePosition_chg, (SUM(table2.Clicks)*table2.revenue_price)/SUM(table2.Impressions) AS Ctr_chg, SUM(table2.Spend)/SUM(table2.Clicks) AS AverageCpc_chg, table2.CurrentMaxCpc as CurrentMaxCpc_chg, SUM(table2.free_joins) AS FreeJoins_chg, SUM(table2.paid_joins) AS PaidJoins_chg
FROM keywords_stats_google_naughtymeetings as table1
LEFT JOIN keywords_stats_google_naughtymeetings as table2
ON table1.keywordId = table2.keywordId
WHERE table1.timeperiod >= '2012-05-21 00:00:00' and table1.timeperiod <= '2012-05-27 00:00:00'
AND table2.timeperiod >= '2012-05-14' and table2.timeperiod <= '2012-05-20'
GROUP BY table1.KeywordId, table1.MatchType, table1.revenue_price, table2.KeywordId, table2.MatchType, table2.revenue_price
ORDER BY FreeJoins
asc
LIMIT 0, 10
Can someone give me an advice how I can get correct SUM results?
I think you need INNER JOIN here. Try to replace the LEFT JOIN with INNER JOIN.
P.S.
I don't get exactly what you want, but I think this idea should be simpler.
(SELECT id, fields_for_first_period_of_time
FROM keywords_stats_google_naughtymeetings) t1
JOIN
(SELECT id, fields_for_second_period_of_time
FROM keywords_stats_google_naughtymeetings) t2
ON t1.id = t2.id
This is just a sketch of the idea. I mean get the results with two separate queries. And then join them. This will be easier for debugging. I hope this can help you.
hi I am doing A query to get some product info, but there is something strange going on, the first query returns resultset fast (.1272s) but the second (note that I just added 1 column) takes forever to complete (28-35s), anyone know what is happening?
query 1
SELECT
p.partnumberp,
p.model,
p.descriptionsmall,
p.brandname,
sum(remainderint) stockint
from
inventario_dbo.inventoryindetails ind
left join purchaseorders.product p on (p.partnumberp = ind.partnumberp)
left join inventario_dbo.inventoryin ins on (ins.inventoryinid= ind.inventoryinid)
group by partnumberp, projectid
query 2
SELECT
p.partnumberp,
p.model,
p.descriptionsmall,
p.brandname,
p.descriptiondetail,
sum(remainderint) stockint
from
inventario_dbo.inventoryindetails inda
left join purchaseorders.product p on (p.partnumberp = inda.partnumberp)
left join inventario_dbo.inventoryin ins on (ins.inventoryinid= inda.inventoryinid)
group by partnumberp, projectid
You shouldn't group by some columns and then select other columns unless you use aggregate functions. Only p.partnumberp and sum(remainderint) make sense here. You're doing a huge join and select and then the results for most rows just end up getting discarded.
You can make the query much faster by doing an inner select first and then joining that to the remaining tables to get your final result for the last few columns.
The inner select should look something like this:
select p.partnumberp, projectid, sum(remainderint) stockint
from inventario_dbo.inventoryindetails ind
left join purchaseorders.product p on (p.partnumberp = ind.partnumberp)
left join inventario_dbo.inventoryin ins on (ins.inventoryinid = ind.inventoryinid)
group by partnumberp, projectid
After the join:
select T1.partnumberp, T1.projectid, p2.model, p2.descriptionsmall, p2.brandname, T1.stockint
from
(select p.partnumberp, projectid, sum(remainderint) stockint
from inventario_dbo.inventoryindetails ind
left join purchaseorders.product p on (p.partnumberp = ind.partnumberp)
left join inventario_dbo.inventoryin ins on (ins.inventoryinid = ind.inventoryinid)
group by partnumberp, projectid) T1
left join purchaseorders.product p2 on (p2.partnumberp = T1.partnumberp)
Is descriptiondetail a really large column? Sounds like it could be a lot of text compared to the other fields based on its name, so maybe it just takes a lot more time to read from disk, but if you could post the schema detail for the purchaseorders.product table or maybe the average length of that column that would help.
Otherswise I would try running the query a few times and see you consistently get the same time results. Could just be load on the database server the time you got the slower result.