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).
Related
I have a query in which I select multiple values. To create my form.
The results look like this :
the last Column [Candidat Nom] is a drop down list with an other query (lets call it Query 1) that select my drop down list values.
The selection is good and is what I'm looking for. Except I get the same value for all lines when they need to be different.
To simplify
let's take the following exemple
I have the following candidate that wants to join for the following job (Represented with their ID).
As we can see 2 candidates wants job N° 12. and 1 candidate for each other job.
What I get
All candidates are listed for every job.
What I want
What I actually did
is I put the following query (Query 1) on my column.
SELECT T_SALARIE.SALARIE_nom & " " & T_SALARIE.SALARIE_prenom AS Candidat Nom
FROM T_EMPLOI INNER JOIN (T_SALARIE INNER JOIN (T_SALARIE_EMPLOI LEFT JOIN T_STATUT_EMPLOI ON T_SALARIE_EMPLOI.SALARIE_EMPLOI_statut_id = T_STATUT_EMPLOI.STATUT_EMPLOI_id) ON T_SALARIE.SALARIE_NNI = T_SALARIE_EMPLOI.SALARIE_EMPLOI_salarie_nni) ON T_EMPLOI.EMPLOI_identifiant = T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant
WHERE (((T_STATUT_EMPLOI.STATUT_EMPLOI_statut) Like "*valid*" Or (T_STATUT_EMPLOI.STATUT_EMPLOI_statut) Like "*décidé*") AND ((T_EMPLOI.EMPLOI_entreprise_id)=1));
This gave me the result I want but with the issue I mentioned previously (Same result for each line)
So
I thought I needed a new Criteria.
I added one, where It's going to select the candidate when the two "emploi ID" of my actual table (Shown before) and the one helping me select the candidates are equal.
With the following query:
SELECT T_SALARIE.SALARIE_nom & " " & T_SALARIE.SALARIE_prenom AS Candidat, T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant
FROM T_EMPLOI INNER JOIN (T_SALARIE INNER JOIN (T_SALARIE_EMPLOI LEFT JOIN T_STATUT_EMPLOI ON T_SALARIE_EMPLOI.SALARIE_EMPLOI_statut_id = T_STATUT_EMPLOI.STATUT_EMPLOI_id) ON T_SALARIE.SALARIE_NNI = T_SALARIE_EMPLOI.SALARIE_EMPLOI_salarie_nni) ON T_EMPLOI.EMPLOI_identifiant = T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant
WHERE (((T_STATUT_EMPLOI.STATUT_EMPLOI_statut) Like "*valid*" Or (T_STATUT_EMPLOI.STATUT_EMPLOI_statut) Like "*décidé*") AND ((T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant)=[R_Select_COMOB]![ACTION_identifiant_emploi]));
But I keep on getting the following pop up that asks me to enter a Job ID
So how can I make the query for each line compare and select the right values?
I hope I was clear in explaining. If not please let me know so that I can add more details.
Thank you !
Thanks to your help and specially #June7 for his propositions, I found a solution regarding my problem :
I added a criteria to select values based on JobID that I wasn't selecting in the first hand.
And then based on the column (jobID) select the values needed
here is my final query :
SELECT
[SALARIE_nom] & " " & [SALARIE_prenom] & " (" & [SALARIE_NNI] & ")" AS Salarié, T_SALARIE_EMPLOI.SALARIE_EMPLOI_salarie_nni, T_SALARIE_EMPLOI.SALARIE_EMPLOI_id, T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant
FROM
(T_STATUT_EMPLOI INNER JOIN T_SALARIE_EMPLOI ON T_STATUT_EMPLOI.STATUT_EMPLOI_id = T_SALARIE_EMPLOI.SALARIE_EMPLOI_statut_id) LEFT JOIN R_Select_Salarie ON T_SALARIE_EMPLOI.SALARIE_EMPLOI_salarie_nni = R_Select_Salarie.SALARIE_NNI
WHERE
(((T_SALARIE_EMPLOI.SALARIE_EMPLOI_emploi_identifiant)=[Formulaires]![F_COMOB]![ACTION_identifiant_emploi]) AND ((T_STATUT_EMPLOI.STATUT_EMPLOI_statut) Like "*validé*") AND ((T_SALARIE_EMPLOI.SALARIE_EMPLOI_Entreprise) Like "*RTE*"));
And Then to update my values for each line. I added a VBA code that requery on input.
Private Sub ACTION_Candidats_P_Enter()
ACTION_Candidats_P.Requery
End Sub
With that my problem is solved.
I've one file xls and in the 1th sheet I've the records of my goods stock, I extract this file each year and i put the result into the last row in the same table.
I try to match the last 3 year, the Article code are UNIQUE but the description has been changed.
There are one way to group by article code, and if the description has changed use the last found?
this is the file
this is my query, I use ADODB.Connection:
SELECT tab1[Codice Articolo], tab1Descrizione, Sum(IIf([anno]=2017,[qta],0)) AS Qta2017, Sum(IIf([anno]=2017,[Tot],0)) AS Val2017, Sum(IIf([anno]=2017,[€Pz],0)) AS Cad2017, Sum(IIf([anno]=2018,[Qta],0)) AS Qta2018, Sum(IIf([anno]=2018,[Tot],0)) AS Val2018, Sum(IIf([anno]=2018,[€pz],0)) AS Cad2018, Sum(IIf([anno]=2019,[Qta],0)) AS Qta2019, Sum(IIf([anno]=2019,[Tot],0)) AS Val2019, Sum(IIf([anno]=2019,[€pz],0)) AS Cad2019
FROM tab1
GROUP BY tab1.[Codice Articolo], tab1.Descrizione;
this is the qry result
and this is that I hope to be possible to have:
I think that I need to use one join with the same table, I try some variant of this code, without right:
SELECT t1[Codice Articolo], t2.Descrizione,(IIf(t1.[anno]=2017,t1.[qta],0)) AS Qta2017, Sum(IIf(t1.[anno]=2017,t1.[Tot],0)) AS Val2017, Sum(IIf(t1.[anno]=2017,t1.[€Pz],0)) AS Cad2017, Sum(IIf(t1.[anno]=2018,t1.[Qta],0)) AS Qta2018, Sum(IIf(t1.[anno]=2018,t1.[Tot],0)) AS Val2018, Sum(IIf(t1.[anno]=2018,t1.[€pz],0)) AS Cad2018, Sum(IIf(t1.[anno]=2019,t1.[Qta],0)) AS Qta2019, Sum(IIf(t1.[anno]=2019,t1.[Tot],0)) AS Val2019, Sum(IIf(t1.[anno]=2019,t1.[€pz],0)) AS Cad2019
FROM tab1 t1
LEFT JOIN (Select t2.Descrizione from Tab1 t2 on t2.anno = max(t1.anno)
LEFT JOIN
GROUP BY tab1[Codice Articolo], t2.Descrizione;
Are the correct way but the errore is on the code ore are wrong the approach?
thank for any suggestions
The problem is with the description, whose value is sometimes equal to the article code, and sometimes not. This creates new groups, which is not what you want.
Here is one way to avoid that:
SELECT
tab1[Codice Articolo],
Max(IIf(tab1[Codice Articolo] <> tab1Descrizione, tab1Descrizione, null)) AS tab1Descrizione
Sum(IIf([anno]=2017,[qta],0)) AS Qta2017,
Sum(IIf([anno]=2017,[Tot],0)) AS Val2017,
...,
Sum(IIf([anno]=2019,[€pz],0)) AS Cad2019
FROM tab1
GROUP BY tab1.[Codice Articolo], tab1.Descrizione;
I was sure that the solution to my problem was with JOIN QUERY, I can't see the light because I needed two JOIN.
this is the solution I found:
strsql = "SELECT t1.[Codice Articolo], t2.Descrizione," & _
"Sum(IIf(t1.[Esercizio]=2017,t1.[NrPz],0)) AS Qta2017," & _
"Sum(IIf(t1.[Esercizio]=2017,t1.[€Tot],0)) AS Val2017," & _
"Sum(IIf(t1.[Esercizio]=2017,t1.[€Pz],0)) AS Cad2017," & _
"Sum(IIf(t1.[Esercizio]=2018,t1.[NrPz],0)) AS Qta2018," & _
"Sum(IIf(t1.[Esercizio]=2018,t1.[€Tot],0)) AS Val2018," & _
"Sum(IIf(t1.[Esercizio]=2018,t1.[€pz],0)) AS Cad2018," & _
"Sum(IIf(t1.[Esercizio]=2019,t1.[NrPz],0)) AS Qta2019," & _
"Sum(IIf(t1.[Esercizio]=2019,t1.[€Tot],0)) AS Val2019," & _
"Sum(IIf(t1.[Esercizio] = 2019, t1.[€pz], 0)) As Cad2019 " & _
"FROM ([temp$] t1 INNER JOIN [temp$] AS t2 ON t1.[Codice Articolo] = t2.[Codice Articolo]) INNER JOIN (SELECT Max([Esercizio]) AS maxdiEsercizio, [Codice Articolo] FROM [temp$] GROUP BY [Codice Articolo]) t3 ON (t2.[Codice Articolo] = t3.[Codice Articolo]) AND (t2.Esercizio = t3.maxdiEsercizio) " & _
"GROUP BY t1.[Codice Articolo], t2.Descrizione;"
Thanks.
fabrizio
I have are resultset based on this SELECT statement:
"SELECT ca.mem_no, me.mem_surname, me.mem_first_name, " +
"lcc.call_cat, ca.call_location, ca.caller_name, lsc.call_sub_cat, ca.call_id, " +
"call_date_start, ca.call_note_start, ca.call_date_end, ca.call_duration, lcs.call_status, " +
"lca.call_action, lcr.call_res, ca.call_note_res\n" +
"FROM tblCall ca\n" +
"INNER JOIN tlkpCallStatus lcs on lcs.callstatus_id = ca.callstatus_id\n" +
"INNER JOIN tlkpCallAction lca on lca.callaction_id = ca.callaction_id\n" +
"INNER JOIN tlkpCallResolution lcr on lcr.callres_id = ca.callres_id\n" +
"LEFT OUTER JOIN tlkpCallSubCategory lsc on lsc.callsubcat_id = ca.callsubcat_id\n" +
"INNER JOIN tlkpCallCategory lcc on lcc.call_cat_id = ca.call_cat_id\n" +
"LEFT OUTER JOIN tblMember me on me.mem_no = ca.mem_no\n" +
"INNER JOIN tblClient cl on cl.client_ident = me.client_ident\n" +
"WHERE me.client_ident = \'AVA\'" +
"AND ca.call_date_start BETWEEN '2017-02-01' AND '2017-02-28'\n" +
"ORDER BY date(ca.call_date_start);\n"
;
which will rst.next() to a speadsheet ... i realize i can get the count of rows by waiting for the processing to finish, however i need the row count prior to writing the report .. i am faced with writing another pre sql statement getting COUNT(*) based upon the same JOIN and WHERE conditions. But i don't want to have two copies of basically the one sql statement ..
Is there a way (JAVA, Sqlite3) i can "SELECT COUNT(*)" from the existing resultset? ... seems a waste to have to go and get them all again just to be able to count the rows. :)
There is a way to probe a JDBC ResultSet and find out how many records are in that result set. But, it might cause the entire result set to be read across the network. Therefore, I vote for just running a separate COUNT(*) query if you really need to find the count. From a network usage point of view, this is very cheap, because you are just asking for a single number to be sent across.
There is also a SQL solution here, which unfortunately is not available for SQLite, which does not support analytic functions (yet). You could use the following query:
SELECT
ca.mem_no,
me.mem_surname,
me.mem_first_name,
COUNT(*) OVER () AS total_record_count -- change here
...
FROM
That is, we can use COUNT as an analytic function to find the total record count at the same time as running the rest of your original query. Again, not available for SQLite, but might be an option for other databases.
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!
In the string below, I am trying to convert the value 'tblContacts.JobTitle from a numerical value to a text value without having to link my query to the table where the original record ('tblJobTitles.JobTitle') sits. The field 'JobTitle' in the table 'tblContacts' pulls it's value from the table 'tblJobTitles'. When I use the query below, unfortunately the query extracts the unique ID number of the job title instead of the text value. Is there to reformat the select query to do so? The below is my code where I thought that you could format the value as text by adding '.text' but unfortunately this doesn't work.
sql_get = "SELECT [tblContacts].[CompleteName], [tblContacts].[CurrentPosition], [tblContacts].[Level], [tblContacts].[ContractType], [tblContacts].[ID], [tblContacts].[Foto], [tblTeams].[Team], [tblJobTitles].[JobTitle] FROM [tblContacts] INNER JOIN [tblTeams] ON [tblContacts].[Team] = [tblTeams].[ID] LEFT JOIN [tblJobTitles] ON [tblJobTitles].[ID] = [tblContacts].[JobTitle] WHERE [tblTeams].[team] = '" & cboDepartments.Value & "'"
Me.frmstaticdatadepartments08.Form.RecordSource = sql_get
As I understand it tblContacts.JobTitle is a foreign key. The actual job title sits in another table, tblJobTitles. The only way to get it is to ask for it, either by a sub-select or by joining in the other table.
SELECT tblContacts.CompleteName, tblContacts.CurrentPosition, tblContacts.Level,
tblContacts.ContractType, tblContacts.ID, tblContacts.Foto,
tblTeams.Team, tblJobTitles.JobTitle
FROM tblContacts
LEFT JOIN tblJobTitles ON tblContacts.JobTitle = tblJobTitles.Id
INNER JOIN tblTeams ON tblContacts.Team = tblTeams.ID
WHERE [tblTeams].[team] = '" & cboDepartments.Value & "'"
I had to guess on the some column names, tblJobTitles.Id and tblJobTitles.JobTitle, but I hope you get my meaning.
The change I did was to join in tblJobTitles and then ask for the title instead of the reference id, tblJobTitles.JobTitle.
Edit:
Apparently Access requires parentheses for multiple joins - see msdn:
In cases where you need to join more than one table, you can nest the INNER JOIN clauses.
So do this instead:
SELECT tblContacts.CompleteName, tblContacts.CurrentPosition, tblContacts.Level,
tblContacts.ContractType, tblContacts.ID, tblContacts.Foto,
tblTeams.Team, tblJobTitles.JobTitle
FROM (tblContacts
INNER JOIN tblTeams ON tblContacts.Team = tblTeams.ID)
LEFT OUTER JOIN tblJobTitles ON tblContacts.JobTitle = tblJobTitles.Id
WHERE [tblTeams].[team] = '" & cboDepartments.Value & "'"