Last Date Attended from 2 Tables SQL Server - 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

Related

Finding the total price for each album [duplicate]

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

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.

How to Correct This SQL CODE?

This is the question using AdvetureWorks2012.
Create a VIEW dbo.vw_Commissions to display the commissions earned last
year by all sales employees. Round the result set to two decimal places and do not include any salesperson who did not earn a commission. Include the
salesperson name, the commission earned, and the job title. Concatenate the
salesperson first and last names.
This code is not working for me. What am I screwing up?
USE AdventureWorks2012
GO
CREATE VIEW dbo.vw_Commissions
AS
SELECT
Sales.SalesPerson.SalesLastYear,
Person.Person.LastName,
Person.Person.FirstName,
HumanResources.Employee.JobTitle
FROM
Sales.SalesPerson
LEFT OUTER JOIN
Sales.SalesPerson ON Sales.SalesPerson.BusinessEntityID = Person.Person.BusinessEntityID
LEFT OUTER JOIN
Person.Person ON Person.Person.BusinessEntityID = HumanResources.Employee.BusinessEntityID
There are multiple problems with your query.
The biggest problem is it is not answering the questions asked. You are selecting SalesLastYear whereas the question asks to calculate the Commissions.
You are not filtering SalesPersons which have not earned any commission.
You need this to run only for last year.
Concatenate the FirstName and LastName.
The error you are getting is because you are using Sales.SalesPerson twice in your query. You need to give them alias names. However, I don't think you need two instances of the same table in this query. Also to use HumanResources.Employee.JobTitle column in the select list, you need to include table HumanResources.Employee in the from list.

Multi join issue

*EDIT** Thanks for all the input, and sorry for late reply. I have been away during the weekend without access to internet. I realized from the answers that I needed to provide more information, so people could understand the problem more throughly so here it comes:
I am migrating an old database design to a new design. The old one is a mess and very confusing ( I haven't been involved in the old design ). I've attached a picture of the relevent part of the old design below:
The table called Item will exist in the new design as well, and it got all columns that I need in the new design as well except one and it is here my problem begin. I need the column which I named 'neededProp' to be associated( with associated I mean like a column in the new Item table in the new design) with each new migrated row from Item.
So for a particular eid in table Environment there can be n entries in table Item. The "corresponding" set exists in table Room. The only way to know which rows that are associated in Item and Room are with the help of the columns "itemId" and "objectId" in the respective table. So for example for a particular eid there might be 100 entries in Item and Room and their "itemId" and "objectId" can be values from 1 to 100, so that column is only unique for a particular eid ( or baseSeq which it is called in table BaseFile).
Basically you can say that the tables Environment and BaseFile reminds of each other and the tables Item and Room reminds of each other. The difference is that some tables lack some columns and other may have some extra. I have no idea why it is designed like this from the beginning.
My question is if someone can help me with creating a query so that I can be able to find out the proper "neededProp" for each row in the Item-table so I can get that data into the new design?
*OLD-PART**This might be a trivial question but I can't get it to work as I want. I want to join a few tables as in the sql-statement below. If I start like this and run this query
select * from Environment e
join items ei on e.eid = ei.eid
I get like 400000 rows which is what I want. However if I add one more line so it looks like this:
select * from Environment e
join items ei on e.eid= ei.eid
left join Room r on e.roomnr = r.roomobjectnr
I get an insane amount of rows so there must be some multiplication going on. I want to get the same amount of rows ( like 400000 in this case ) even after joining the third table. Is that possible somehow? Maybe like creating a temporary view with the first 2 rows.
I am using MSSQL server.
So without knowing what data you have in your second query it's very difficult to say exactly how to write this out, and you're likely having a problem where there's an additional column that you are joining to in Rooms that perhaps you have forgotten such as something indicating a facility or hallway perhaps where you have multiple 'Room 1' entries as an example.
However, to answer your question regarding another way to write this out without using a temp table I've crufted up the below as an example of using a common table expression which will only return one record per source row.
;WITH cte_EnvironmentItems AS (
SELECT *
FROM Environment E
INNER JOIN Items I ON I.eid = E.eid
), cte_RankedRoom AS (
SELECT *
,ROW_NUMBER() OVER (ORDER BY R.UpdateDate DESC) [RN]
FROM Room R
)
SELECT *
FROM cte_EnvironmentItems E
LEFT JOIN cte_RankedRoom R ON E.roomnr = R.roomobjectnr
AND R.RN = 1
btw,do you want column from room table.if no then
select * from Environment e
join items ei on e.eid= ei.eid
where e.roomnr in (select r.roomobjectnr from Room r )
else
select * from Environment e
join items ei on e.eid= ei.eid
left join (select distinct roomobjectnr from Room) r on e.roomnr = r.roomobjectnr

Resources