Finding the total price for each album [duplicate] - database

I have 9 items in a problem_categories tables that have category_id = 1
When I do this query:
select problems.problem_id , problem_title , sum( vote ) as totalVotes
from problems
left join problem_votes on problems.problem_id = problem_votes.problem_id
left join problem_categories on problems.problem_id = problem_categories.problem_id
where problem_categories.category_id = 1;
I get 1 row with a complete sum of all the votes for the 9 items. But what I was really looking for was the 9 rows with a vote sum for each. Any idea what is wrong with my query just by looking at it?
My tables are
problem - lists problem information
problem_votes - has a record per vote for each problem
problem_categories - table keeping a problem_id and a category_id so that a problem can be in a certain category
Thanks,
Alex

You need to tell MySQL what you're grouping by. Right now it thinks you want EVERYTHING grouped into one row. If you want it to by grouped by problem_title, then add in this line after your WHERE:
GROUP BY problem_title
This will cause you to get a different row for each unique problem_title, and the sum will only count records matching that title.
Edit:
So the whole query will look something like this:
select problems.problem_id , problem_title , sum( vote ) as totalVotes
from problems
left join problem_votes on problems.problem_id = problem_votes.problem_id
left join problem_categories on problems.problem_id = problem_categories.problem_id
where problem_categories.category_id = 1
group by problem_title;

Just an FYI, most versions of SQL do not accept group by statements that do not include all non-aggregate columns. So if you're ever working with some other SQL software, you'll likely need to include problems.problem_id and problem_title.
For more on this issue, see this thread: Do all columns in a SELECT list have to appear in a GROUP BY clause

Related

Duplicate SQL Record Entries with in 3 days

Table has following structure
ID, OrderNumber, PFirstName, PLastName, Product, LastDateModified
This information is populated into my SQL Server database by a XML import file and is created when the front end hits 'Enter'. But someone on the front has been seeing an error and then hitting Cancel and re-submitting the order with new information.
Now, the first order is in the Database because they didn't cancel it out on the backend first.
How can I find the any duplicate OrderNumber, PFirstName, PLastName, Product within 3 days of any lastdatemodified entry?
A self join with a simple where clause.
Assuming the ORDER numbers are not duplicated and that's what you're looking for.
SELECT A.ID as A_ID
, A.orderNumber as OriginalOrder
, B.ID as B_ID
, B.OrderNumber as PossibleDuplicatedOrder
FROM TBL A
INNER JOIN TBL B
on A.PFirstName = B.PfirstName
AND A.PLastName = B.PLastName
AND A.Product = B.Product
AND A.LastDateMOdified < B.LastDateModified
WHERE datediff(day,A.LastDateModified,B.LastDateModified) <=3
Logically this self joins and to eliminate A-->B and B-->A duplication casued by self joins we use a < so that all of the records in alias A have a date earlier than that in B when the other fields are equal, and then we simply look for those that have a datediff of <=3.
However if multiple duplicates exist for the same order such as
A-->B
B-->C
You'll see duplication in the results such as (but only if all 3 are w/in 3 days)
A-->B
B-->C
A-->C
But I don't see this as a bad thing given what you're attempting to recover from.
I'm not sure how to determine if it's been cancelled or backed out so you'll have to set other limits for that as they weren't specified in the question.

SQL SUM() function with parameters returned by query for each row

First of all, sorry for that weird title. Here is the thing:
I work for a online shop, which sells products on amazon. Since we sell sets of different items, it happens that we send the same item within multiple sets to amazon fba. To give out the total sum of one item in all sets, I wrote the following query:
SELECT
SUM(nQuantity)
AS [total]
FROM [amazon_fba]
INNER JOIN (SELECT
[cArtNr]
FROM [tArtikel]
INNER JOIN (SELECT
[kStueckliste]
FROM [tStueckliste]
WHERE [kArtikel] = (SELECT
[kArtikel]
FROM [tArtikel]
WHERE [cHAN] = 12345)) [bar]
ON [tArtikel].[kStueckliste] = [bar].[kStueckliste]) [foo]
ON [amazon_fba].[cSellerSKU] = [foo].[cArtNr]
The cHAN=12345 part is just used to pick one specific item for which we want to know the total number of items. This query itself works fine, so this is not the problem.
However, I also know that all products that are part of sets have [tArtikel].[kStueckliste]=0, which -in theory- makes identifying them pretty easy. Which got me to the idea, that I could use this query to instantly generate a list of all these products with their respective total, like:
kArtikel | total
=================
01234 | 23
56789 | 42
So basically I needed something like
foreach (
select [kArtikel]
from [tArtikel]
where [tArtikel].[kStueckliste]=0
) do (
< the query I made >
)
Thus I tried the following statement:
SELECT
SUM(nQuantity)
AS [total]
FROM [amazon_fba]
INNER JOIN (SELECT
[cArtNr]
FROM [tArtikel]
INNER JOIN (SELECT
[kStueckliste]
FROM [tStueckliste]
INNER JOIN (SELECT
[kArtikel]
FROM [tArtikel]
WHERE [tArtikel].[tStueckliste] = 0) [baz]
ON [tStueckliste].[kArtikel] = [baz].[kArtikel]) [bar]
ON [tArtikel].[kStueckliste] = [bar].[kStueckliste]) [foo]
ON [amazon_fba].[cSellerSKU] = [foo].[cArtNr]
This did not -as I hoped- return a list of sums, but instead gave me the total sum of all sums I wanted to create.
Since I am pretty new to SQL (about two weeks in maybe), I have neither any idea what to do, nor where my mistake is, NOR what phrasing I should use to google my way around -thus that wierd Title of this post. So if anyone could help me with that and/or point me into the right direction I'd be really happy :)
I write MySQL rather than SQL but I believe it's very similar other than a few functions and syntaxes. Here's what I think should work for you:
select am.cArtNr, sum(am.nQuantity) as total
from amazon_fba am
join tArtikel ar on ar.cArtNr=am.cArtNr
join tStueckliste st on st.kStueckliste=ar.kStueckliste
where ar.kStueckliste=0
group by am.cArtNr;
Adding the group by will do the split out by articles, but reducing the number of brackets (in this instance derived tables) will speed up the query provided you're using indexes. Again, this is how I would do it in MySQL, and the only other query language I have experience in is BigQuery which won't help here.

Last Date Attended from 2 Tables SQL Server

I have searched the forum, and couldn't find an answer. So I apologize if this is out there. This seems simple in my mind, however, I can't seem to get the correct code.
I have 2 tables. STUDENT_TERMS_VIEW table holds STTR_STUDENT, STTR_TERM and TERMS table, holds the TERM_END_DATE. I need to find a way to select the student's last term based on MAX(TERM_END_DATE), but I get STTR_TERM duplicate rows per student. I need to get 1 row per student and their last term attended.
EDIT: Ok so both tables are linked by TERM.
View Code Here
As you can see, I am getting duplicate TERMS for the same student, even though I am pulling MAX(TERM_END_DATE)
SELECT * FROM
(SELECT STUDENT_TERMS_VIEW.STTR_STUDENT,
STUDENT_TERMS_VIEW.STTR_TERM,
TERMS.TERM_END_DATE
FROM STUDENT_TERMS_VIEW
JOIN STUDENT_TERMS_VIEW ON TERMS.TERMS_ID = STUDENT_TERMS_VIEW.STTR_TERM
ORDER BY TERMS.TERM_END_DATE DESC,STUDENT_TERMS_VIEW.STTR_STUDENT)
GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT
Your query is getting the max of the combination of (STTR_STUDENT and STTR_TERM). If you only want to get the max term of each student, you should only GROUP BY STUDENT_TERMS_VIEW.STTR_STUDENT. Try the query below.
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE)
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
If you also need to get the term, join it back to STUDENT_TERMS_VIEW and TERMS.
SELECT s.STTR_STUDENT, s.STTR_TERM, t.TERM_END_DATE
FROM (
SELECT stv.STTR_STUDENT, MAX(t.TERM_END_DATE) AS 'MaxDate'
FROM STUDENT_TERMS_VIEW stv
JOIN TERMS t ON t.TERMS_ID = stv.STTR_TERM
GROUP BY stv.STTR_STUDENT
) a
JOIN STUDENT_TERMS_VIEW s ON s.STTR_STUDENT = a.STTR_STUDENT
JOIN TERMS t ON t.TERMS_ID = s.STTR_TERM AND t.TERM_END_DATE = a.TERM_END_DATE

How to get quantity and weight per category via subquery in SQL Server 2012?

I have three tables
items
ItemCategories
ItemsToPackingLists
I would like to know how to extend the following query to have:
the Quantity of Items per ItemCategory too (SumItemsOfCategory)
the Weight of Items per ItemCategory (SumWeightOfItemsOfCategory).
The subquery to calculate ItemsOfPacklist does work already. Any help is appreciated.
SELECT items.ID,
items.NameOfItem,
items.WeightInGrams,
ICategories.NameOfCategory,
IToPLs.Quantity,
(items.WeightInGrams * IToPLs.Quantity) AS TotalWeightInGrams,
(SELECT SUM(IToPLs2.Quantity)
FROM ItemsToPackingLists AS IToPLs2
WHERE PackingListID = 1
) AS ItemsOfPackingList
FROM trekking_Items AS items
LEFT JOIN ItemCategories AS ICategories ON
items.ItemCategoryID = ICategories.ID
LEFT OUTER JOIN ItemsToPackingLists AS IToPLs ON
items.ID = IToPLs.ItemID
WHERE PackingListID = 1
ORDER BY ICategories.SortID ASC
Do you want to see these two pieces of data per detail row? If so, I'd recommend using window functions. MSDN: https://msdn.microsoft.com/en-us/library/ms189461.aspx
You could add something along the lines of:
SELECT...
COUNT(items.ID) OVER(PARTITION BY items.ItemCategoryID) AS SumItemsOfCategory,
SUM(items.WeightInGrams * IToPLs.Quantity) OVER(PARTITION BY items.ItemCategoryID) AS SumWeightOfItemsOfCategory
FROM...
Edit: In response to OP's comment. That was an oversight on my part. I've modified the example to take into account the number of items for the weight per category computation.

SQL Server - Count the number of times the contents of a specified field repeat in a table

What's the best way to 'SELECT' a 'DISTINCT' list of a field from a table / view (with 'WHERE' criteria) and alongside that count the number of times that that field content repeats in the table / view?
In other words, I have an initial view that looks a bit like this:
I'd like a single SQL query to filter it (SELECT...WHERE...) so that we are only considering records where [ORDER COMPLETE] = False and [PERSONAL] = Null...
...and then create a distinct list of names with counts of the number of times each name appears in the previous table:
*Displaying the [ORDER COMPLETE] and [PERSONAL] fields is redundant by this point and could be dropped to simplify.
I can do the steps individually as above, but struggling to get a single query to do it all... any help appreciated!
Thanks in advance,
-Tim
This should just be the following
SELECT dbo.tblPerson.Person,
COUNT(dbo.tblPerson.Person) AS Count
FROM dbo.tblPerson
INNER JOIN dbo.tblNotifications ON dbo.tblPerson.PersonID = dbo.tblNotifications.AddresseeID
WHERE dbo.tblNotifications.Complete = 'False'
AND dbo.tblNotifications.Personal IS NULL
GROUP BY dbo.tblPerson.Person
ORDER BY COUNT(dbo.tblPerson.Person) DESC
You don't need your DISTINCT or TOP 100 PERCENT,
Here is a simplified fiddle
Well I got downvoted into oblivion (probably for displaying the full extent of my own ignorance!), but just in case someone from the future experiences the same problem as me and stumbles across this question while Googling (or whatever verb you use for "searching all digitised human knowledge" in the distant future), here's some sanitised code of the query I managed to get to work in the end - thanks to Mark Sinkinson's snippet for helping me realise the obvious...
SELECT DISTINCT TOP (100) PERCENT dbo.tblPerson.Person, COUNT(dbo.tblPerson.Person) AS CountPerson
FROM dbo.tblPerson INNER JOIN
dbo.tblNotifications ON dbo.tblPerson.PersonID = dbo.tblNotifications.AddresseeID
WHERE (dbo.tblNotifications.Complete = 'False') AND (dbo.tblNotifications.Personal IS NULL)
GROUP BY dbo.tblPerson.Person
ORDER BY CountPerson DESC

Resources