SQL - select 5 columns where 3 are distinct using multiple JOINs - sql

I searched Stack Overflow before asking and looked through the 5 most relevant questions, but they did not seem to answer this.
I need to select 5 columns from a table using multiple INNER JOINs, but I only want to get the records where 3 of the 5 columns are distinct. If I use:
"select DISTINCT pos_segments.pos, ",
" pos_segments.org, ",
" pos_segments.obj, ",
" pos_segments.proja, ",
" pos_segments.eff_dt ",
" from pos_segments ",
"INNER JOIN PersonnelPositions ",
"ON pos_segments.pos = PersonnelPositions.Position ",
"AND pos_segments.eff_dt = PersonnelPositions.EffectiveDate ",
"INNER JOIN Accounts ",
"ON PersonnelPositions.PayrollGLAccountId = Accounts.Id ",
" WHERE <where clause here>
I get back over 22k records. I need to get the pos_segments columns only where the combination of the following three columns are distinct:
pos_segments.pos, pos_segments.proja, pos_segments.eff_dt
These three columns taken together serve as a unique key for this table. How can I only get back the records which are distinct based on the combination of these three columns?
P.S. - we are using MS SQL Server
Thanks!

Edit: As Sean pointed out, the ORDER BY statement is not optional. I never tried without it so I wasn't sure. And it would appear that the code block below is more of a suggestion than a copy paste so take it with a grain of salt. However, this approach should still work with some tweaking to fit your application. Since you mentioned that it may be arbitrary which distinct row is grabbed, you can put either of the other two columns after the ORDER BY statement.
I very recently needed to solve a very similar issue. I was able to accomplish what I needed by using a partition in conjunction with a where statement. You code would be modified to look like this:
"select * from ("
"select ROW_NUMBER() OVER (PARTITION BY pos_segments.pos,
pos_segments.proja, pos_segments.eff_dt ORDER BY pos_segments.org)
AS row_num_throwaway"
" pos_segments.pos, ",
" pos_segments.org, ",
" pos_segments.obj, ",
" pos_segments.proja, ",
" pos_segments.eff_dt ",
" from pos_segments ",
"INNER JOIN PersonnelPositions ",
"ON pos_segments.pos = PersonnelPositions.Position ",
"AND pos_segments.eff_dt = PersonnelPositions.EffectiveDate ",
"INNER JOIN Accounts ",
"ON PersonnelPositions.PayrollGLAccountId = Accounts.Id ",
" WHERE <where clause here>)"
"WHERE row_num_throwaway = 1"
That first row_number partition line just finds distinct versions of the three columns specified and assigns a row number that counts up as more instances of that distinct group are found. By only looking where row_num_throwaway = 1, you are only getting the first time that combo is present. To ensure you retrieve the correct entry, you can always add an ORDER BY statement where I showed with the stars.
Hope this helps!

Related

Access SQL formatting question inner join with subselect

I have some access DB tables. EMails with a subject line, Emp_Names with FN and LN, and keywords keywords.
I want to get all emails with a subject line that has the keywords and doesn't have any of the Employee's first and last name.
First part is easy:
Select * From Emails Inner Join keywords on InStr(" " & Emails.Subject, " " & keywords.keywords)
The space is added to if a keyword is Pinion I won't get opinion and adding to start of subject if it exists as first word.
However, I can't seem to either properly SQL Code access to Select the derivative Table to only include those subject of emails where Emp_Names.FN and LN don't appear in the subject. I've tried sub-selecting a derivative table of just the subjects without employee names before looking for keywords, but I always get syntax errors.
SELECT * From (
Select * From Emails inner Join Emp_names on InStr(Emails.subject, emp_names.FN & " " emp_names.LN)=0)
Inner Join keywords on InStr(" " & Emails.Subject, " " & keywords.keywords)
I get syntax error on Join Operation, highlights Emails first instance.

hibernate sql query with distinct and order by

I have this query:
"select distinct d from Dance d " +
"inner join d.meisterschaftDances ms " +
"inner join ms.danceRegistrations dr " +
"inner join dr.user u " +
"where (u.id = :userId " +
"or d.user.id = :userId) " +
"AND ms.meisterschaft.open = FALSE " +
"order by ms.meisterschaft.organizer.id, " +
"d.discipline, d.age, d.category, " +
"d.class"
The logic would be perfect for me but as we know distinct is not so easy with order by.
I get the same dance several times because the inner join to meisterschaftDances can have several references.
Sadly I dont know how to rewrite my query in such a way that it is working. Can somebody show me an example which would work. Thanks
As it's stated in the hibernate documentation:
For JPQL and HQL, DISTINCT has two meanings:
It can be passed to the database so that duplicates are removed from a result set
It can be used to filter out the same parent entity references when join fetching a child collection
You are interested in the second case, so, you need to add the QueryHints.HINT_PASS_DISTINCT_THROUGH hint, like below:
List<Dance> dances = entityManager.createQuery(
"select distinct d " +
"from Dance d " +
"inner join d.meisterschaftDances ms ...", Dance.class)
.setHint( QueryHints.HINT_PASS_DISTINCT_THROUGH, false )
.getResultList();
P.S. But the above approach may be not workable in some hibernate versions due to bugs (See for example HHH-13517 and HHH-13280)

Access VBA How to use a Union ALL statement

My UNION ALL statement is not returning what I hoped it would. I am putting products into a location (73) and taking them out of the same location. I would like to know how many are remaining in that location. I am trying to figure this out by adding the amount in and subtracting the amount out. I am storing my transactions in tblWarehouseTransfer.
I would like to have one line for each product with the total. What I am getting is one line with the sum of the amount put into the location and one line with the sum of the amount taken out (as a negative number).
I am using a list box to display the list of all my products.
Me.lstCutWipers.RowSource = "SELECT tblProducts.ProductID, tblProducts.ProductName, Sum(tblWarehouseTransfer.Qty) AS SumOfQty " _
& " FROM tblWarehouseTransfer INNER JOIN tblProducts ON tblWarehouseTransfer.ProductID = tblProducts.ProductID " _
& " GROUP BY tblProducts.Productid, tblProducts.ProductName, tblWarehouseTransfer.LocationTo " _
& " HAVING (((tblWarehouseTransfer.LocationTo) = 73)) " _
& " UNION ALL SELECT tblProducts.ProductID, tblProducts.ProductName, -Sum(tblWarehouseTransfer.Qty) AS SumOfQty " _
& " FROM tblWarehouseTransfer INNER JOIN tblProducts ON tblWarehouseTransfer.ProductID = tblProducts.ProductID " _
& " GROUP BY tblProducts.Productid, tblProducts.ProductName, tblWarehouseTransfer.LocationFrom " _
& " HAVING (((tblWarehouseTransfer.LocationFrom)= 73))"
Can someone help me to join the 'in' and the 'out' as one total.
This example joins two subqueries which allows your two different sums to be added together, whereas a UNION only lists rows of the two queries together.
One downside to having subqueries is that it cannot be fully edited in query Design View... it requires the SQL View to edit the whole thing. BUT, you could save each subquery separately and then join those queries together in a third query. Then you could edit each part separately in Design View.
Also notice that I changed the HAVING clause to a WHERE clause. WHERE clauses can be more efficient if you are applying criteria to source values before they are aggregated (i.e. grouped and summed). HAVING applies the criteria after aggregating the data. If the criteria involves aggregate expressions, then they must appear in HAVING clause.
By changing to a WHERE clause it also means that you don't have to group on that field. The difference in speed may be negligible and it should return the same information, but just not necessary since every row contributing to that query will only be for the value in the WHERE clause. Just be aware that if you change the query at all, you need to consider the proper clause to apply criteria.
EDIT: Changed to LEFT JOIN and handled NULL in TotalSum with call to nz().
SELECT ToQuery.ProductID, ToQuery.ProductName, (ToQuery.SumOfQty + nz(FromQuery.SumOfQty, 0.0)) As TotalSum
FROM
(SELECT tblProducts.ProductID, tblProducts.ProductName, Sum(tblWarehouseTransfer.Qty) AS SumOfQty
FROM tblWarehouseTransfer INNER JOIN tblProducts ON tblWarehouseTransfer.ProductID = tblProducts.ProductID
WHERE tblWarehouseTransfer.LocationTo = 73
GROUP BY tblProducts.Productid, tblProducts.ProductName) AS ToQuery
LEFT JOIN
(SELECT tblProducts.ProductID, tblProducts.ProductName, -Sum(tblWarehouseTransfer.Qty) AS SumOfQty
FROM tblWarehouseTransfer INNER JOIN tblProducts ON tblWarehouseTransfer.ProductID = tblProducts.ProductID
WHERE tblWarehouseTransfer.LocationFrom = 73
GROUP BY tblProducts.Productid, tblProducts.ProductName) AS FromQuery
ON ToQuery.ProductID = FromQuery.ProductID
To be complete, this assumes that ProductID is a primary key and that ProductName is unique to each ProductID. If that is not true, you will need to change the outer query ON expression to match ProductName values as well (i.e. add AND ToQuery.ProductName = FromQuery.ProductName).

How do code (SQL) a combo box to display data from a field in a table, minus data which is also in another table?

I'm using SQL to code a combobox which will display names from one table (students), minus any students in my other table (Bookings) who have made a booking on a specific day.
In my "students" table I have one field, "Name". In my "Bookings" table I have two fields, "Name" and "Day".
Here is the code I am using to tell what is going in my combobox;
Combobox.RowSource = "SELECT Name FROM Students" & _
"LEFT OUTER JOIN Bookings " & _
"ON Students.Name = Bookings.Name" & _
"WHERE Bookings.Day = 'Monday';"
To my knowledge this should display all of the names in Students.Name minus any names in Bookings which are on the day Monday. But it's just opening an error message "Syntax error in FROM clause."
Thanks in advance for any advice.
Udate:
I found out how to make it work. Instead of a "Left Outer Join" you have to use a "Not In" clause.
Here' s the code I used.
combobox.RowSource = "SELECT Name FROM Students " & _
"WHERE Name " & _
"NOT IN (SELECT Bookings.Name FROM Bookings WHERE Bookings.Day = ""Monday"") "

SQL joining issue - 1 table in multiple join missing an entry

I have a query that joins multiple tables.
QString str1 = "SELECT DISTINCT f.pk_file_ID, f.file_name"
" FROM"
" File_Properties f"
", Video v "
", Audio a"
", Transport_Stream ts"
", TS_Data tsd"
", Signal_Root sr"
", Test_Case tc"
" WHERE"
" v.fk_file_ID = f.pk_file_ID"
" AND a.fk_file_ID = f.pk_file_ID"
" AND ts.fk_file_ID = f.pk_file_ID"
" AND tsd.fk_file_ID = f.pk_file_ID"
" AND sr.fk_file_ID = f.pk_file_ID"
" AND tc.fk_file_ID = f.pk_file_ID" + clause;
My app uses comboboxes that allow a user to select video file criteria which is used to fetched and display file data in a table. The selected criteria is stored in the clause variable and is used to retrieve the matching files in the database.
The problem here is that a video file can have 0 to many Audio and Video entries. If, for example, a file does not contain any Audio data, there is no entry made in the Audio table. Therefore, this join does not work for retrieving files that do not have an Audio/Video entry.
One way around this would be to make a blank record in the tables where a video file has no Audio/Video data. However, I don't want to have blank records in the tables.
Is there a better way to join the tables?
Thanks
Have a look at the Left outer Join. Values of the left (in this case file_properties) table are always displayed, even when they have no corresponding record in the right (in this case audio and video) table.