SQL JOIN Master group to Result group - sql

I am using Excel VBA and connecting to PGSQL using OleDB. I have 2 lines of SQL code that work fine on there own, but I now need to merge them.
The 1st query is the master group that finds the people I need for the 2nd query
Const sqlconnection = "Provider=oledb;"
Dim conn As New Connection
conn.ConnectionString = sqlconnection
conn.Open
Dim rs As Recordset
Sheets("Sheet1").Select
Range("A1").Select
Dim GRP As String
GRP = "SELECT h.master_id, p.surname, p.forename1, h.eventdate, h.code " _
& "FROM hist h INNER JOIN person p ON h.master_id=p.entity_id " _
& "AND code LIKE 'C10%' " _
& "ORDER BY h.master_id "
The 2nd query needs to show the results based on the 1st group of people it found.
Dim DATA As String
DATA = "SELECT latest.master_id, p.surname, p.forename1, " _
& "SUBSTRING(latestAP,1,10) eventdate, " _
& "SUBSTRING(latestAP,12,3) TX1, " _
& "SUBSTRING(latestAP,16,3) TX2 " _
& "FROM ( " _
& "SELECT master_id, " _
& "MAX(CAST(eventdate AS VARCHAR(10)) + '.' + RIGHT('00' + TEXT1,3)+ '.' + RIGHT('00' + TEXT2,3)) as latestAP " _
& "FROM ap " _
& "GROUP BY master_id) AS latest " _
& "LEFT JOIN person p ON latest.master_id = p.entity_id " _
& "ORDER BY master_id "
Set rs = conn.Execute(DATA)
With ActiveSheet.QueryTables.Add(Connection:=rs, Destination:=Range("A1"))
.Refresh
End With
rs.Close

Consider adding first query as an additional derived table to second query:
Dim DATA As String
DATA = "SELECT latest.master_id, p.surname, p.forename1, " _
& " SUBSTRING(latestAP,1,10) eventdate, " _
& " SUBSTRING(latestAP,12,3) TX1, " _
& " SUBSTRING(latestAP,16,3) TX2 " _
& "FROM ( " _
& " SELECT master_id, " _
& " MAX(CAST(eventdate AS VARCHAR(10)) + '.' + " _
& " RIGHT('00' + TEXT1,3) + '.' + " _
& " RIGHT('00' + TEXT2,3)) as latestAP " _
& " FROM ap " _
& " GROUP BY master_id) AS latest " _
& "INNER JOIN ( " _
& " SELECT h.master_id, p.surname, p.forename1, "_
& " h.eventdate, h.code " _
& " FROM hist h " _
& " INNER JOIN person p ON h.master_id=p.entity_id " _
& " AND code LIKE 'C10%') AS grp "
& "ON grp.master_id = latest.master_id"
& "LEFT JOIN person p ON latest.master_id = p.entity_id " _
& "ORDER BY master_id "

Related

Encountered error Syntax error in JOIN operation

OBJECTIVE: trying to extract data using union all with join.
CODE:
MYSQL = "SELECT trans_id, item_id, SUM(OrigQty) AS NewOrigQty, SUM(TempQty) AS NewTempQty, " & _
"itm_name, itm_category, itm_details, itm_um, itm_cost " & _
"FROM (" & _
"SELECT T1.trans_id, T1.item_id, T1.itm_qty AS OrigQty, 0 AS TempQty, " & _
"T3.itm_name, T3.itm_category, T3.itm_details, T3.itm_um, T3.itm_cost FROM INVENTORY AS T1 " & _
"LEFT JOIN ITEM AS T3 ON T1.item_id = T3.itm_id " & _
"WHERE T1.trans_id = '" & NewSearchList.lvSearchWindow.SelectedItem.Text & "' " & _
"AND T1.itm_movement = 'TRANSFER IN' AND T1.inv_temporig_status = 'ORIGINAL' " & _
"UNION ALL " & _
"SELECT T2.trans_id, T2.item_id, 0 AS OrigQty, T2.itm_qty AS TempQty, " & _
"t4.itm_name, t4.itm_category, t4.itm_details, t4.itm_um, t4.itm_cost FROM INVENTORY AS T2 " & _
"LEFT JOIN ITEM AS t4 ON T1.item_id = T4.itm_id " & _
"WHERE T2.trans_id = '" & NewSearchList.lvSearchWindow.SelectedItem.Text & "' " & _
"AND T2.itm_movement = 'TRANSFER IN' AND T2.inv_temporig_status = 'TEMPORARY' " & _
") x " & _
"GROUP BY trans_id, item_id, itm_name, itm_category, itm_details, itm_um, itm_cost"
Set rsInventory = dbInventory.Execute(MYSQL)
ERROR: Syntax error in JOIN operation

SQL where with Union and Left

Is it possible to add criteria in [ID] and not in [TypeID] in Left Join?
SQL = "SELECT " & _
"ADate As NewDate, " & _
"tblA.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblA " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblA.TypeID " & _
"WHERE tblA.TypeID = " & Counter & " " & _ => Delete this one.
"UNION ALL SELECT " & _
"BDate As NewDate, " & _
"tblB.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblB " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblB.TypeID " & _
"WHERE tblB.TypeID = " & Counter & " " & _ => Delete this one.
===
and place one WHERE on ID here
"WHERE ID = " & Counter & " " & _ => Like this one. But I am getting an error.
===
"ORDER BY NewDate;"
Delete the two WHERE from tblA and tblB.
Add one in ID in the end.
And create this one.
SQL = "SELECT " & _
"ADate As NewDate, " & _
"tblA.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblA " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblA.TypeID " & _
"UNION ALL SELECT " & _
"BDate As NewDate, " & _
"tblB.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblB " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblB.TypeID " & _
"WHERE tblB.TypeID = " & Counter & " " & _
"WHERE ID = " & Counter & " " & _
"ORDER BY NewDate;"
Thank you in advance.
You can check for ID's only once by wrapping your entire query in a subquery, and then check for IDs in the outer query, e.g.:
SELECT * FROM (
SELECT " & _
"ADate As NewDate, " & _
"tblA.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblA " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblA.TypeID " & _
"UNION ALL SELECT " & _
"BDate As NewDate, " & _
"tblB.TypeID as ID, " & _
"tblAB.TypeControl as ControlID " & _
"FROM tblB " & _
"LEFT OUTER JOIN tblAB " & _
"ON tblAB.TypeID = tblB.TypeID "
) WHERE ID = " & Counter & "
However, depending on how the database engine optimizes this, it might take longer to execute. I recommend you don't do this, and leave your query as-is.
(Also, I leave the quotes mess to you, since your question shouldn't have these anyway).

WHERE clause makes LEFT JOIN work like an INNER JOIN

I am trying to left join three tables with a where clause. In the first example
the query results in an inner join. If I take out the where clause it results in a left join, but in includes records outside the desired date range.
I'm using Microsoft Access 2010 and Visual Basic 2010.
strQry = " SELECT tblUnits.UnitNumber, TenantName, SchedRent, SchedCAM, sum(AMOUNT) as SUMAMOUNT " _
& " FROM ((tblUnits LEFT JOIN tblTenants ON tblTenants.Unitptr = tblUnits.ID) " _
& " LEFT JOIN tblTrans ON (tblTenants.ID = tblTrans.id) ) " _
& " WHERE (tblTrans.PostDate BETWEEN #" & txtStartDate.Text & "# AND #" & txtEndDate.Text & "# ) " _
& " GROUP BY tblUnits.UnitNumber, TenantName, SchedRent, SchedCAM " _
& " ORDER BY tblUnits.UnitNumber "
In the second example it works perfectly, but only joins two tables
strQry = " SELECT U.UnitNumber, sum(AMOUNT) as sumamount " _
& " FROM tblUnits AS U " _
& " LEFT JOIN " _
& " ( " _
& " SELECT * " _
& " FROM tblTrans " _
& " WHERE (tblTrans.PostDate BETWEEN #" & txtStartDate.Text & "# AND #" & txtEndDate.Text & "# ) " _
& " ) as X " _
& " ON U.ID = X.ID " _
& " GROUP BY U.UnitNumber "
I can't get the syntax correct when I try to join the third table
Try WHERE tblTrans.PostDate IS NULL OR ...
As it stands, your LEFT JOIN includes tblUnits rows for which there is no matching tblTrans row. Then your WHERE clause eliminates these rows.
The following works
strQry = " SELECT U.UnitNumber, T.TenantName, T.SchedRent, T.SchedCAM, sum(AMOUNT) as SUMAMOUNT " _
& " FROM ((tblUnits AS U " _
& " LEFT JOIN tblTenants as T ON U.ID = T.UnitPtr) " _
& " LEFT JOIN " _
& " ( " _
& " SELECT * " _
& " FROM tblTrans " _
& " WHERE (tblTrans.PostDate BETWEEN #" & txtStartDate.Text & "# AND #" & txtEndDate.Text & "# ) " _
& " ) as X " _
& " ON U.ID = X.ID) " _
& " GROUP BY U.UnitNumber, TenantName, SchedRent, SchedCAM " _
& " ORDER BY U.UnitNumber "

Query - Error assigning value to variable in VB

I have the following code to query in VB6:
SQL = " if object_id('tempdb..#MovSeq','U') is not null drop table #MovSeq;" & _
" declare #Data_Inicio datetime, #Data_Fim datetime; set dateformat dmy; set #Data_Inicio = DataInicio; set #Data_Fim = DataFinal; set #Data_Fim = DateAdd(day, +1, #Data_Fim); " & _
" with Mov as ( SELECT EI.Cod_Empresa, EI.Cod_Estoque, EI.Cod_Produto, 'E' as Tipo_Mov, E.Dta_Entrada as Data_Mov, EI.id_Doc as NF, EI.Qtde, EI.V_Unitario, EI.V_Total " & _
" from Entrada_Itens as EI inner join Entrada as E on EI.Cod_Empresa=E.Cod_Empresa and EI.id_Doc=E.id_Doc " & _
" where E.Dta_Entrada >= #Data_Inicio and EI.Cod_Empresa='" & Sys.Empresa & "' and EI.Cod_Estoque='" & dcEstoque.BoundText & "' and EI.Cod_Produto='" & dtProdutos.BoundText & "' " & _
" Union " & _
" SELECT SI.Cod_Empresa, SI.Cod_Estoque, SI.Cod_Produto, 'S', S.Dta_Entrada , SI.id_Doc, -SI.Qtde, SI.V_Unitario, SI.V_Total " & _
" from Saida_Itens as SI inner join Saida as S on SI.Cod_Empresa=S.Cod_Empresa and SI.id_Doc=S.id_Doc " & _
" where S.Dta_Entrada >= #Data_Inicio and SI.Cod_Empresa='" & Sys.Empresa & "' and SI.Cod_Estoque='" & dcEstoque.BoundText & "' and SI.Cod_Produto='" & dtProdutos.BoundText & "' " & _
" Union " & _
" SELECT Cod_Empresa, Cod_Estoque, Cod_Produto, 'A', #Data_Inicio, null, null, null, null " & _
" From Estoque " & _
" where Cod_Empresa='" & Sys.Empresa & "' and Cod_Estoque='" & dcEstoque.BoundText & "' and Cod_Produto='" & dtProdutos.BoundText & "') " & _
" SELECT *, Seq= row_number() over (partition by Cod_Empresa, Cod_Estoque, Cod_Produto order by Data_Mov desc, Tipo_Mov desc) into #MovSeq from Mov; " & _
" create unique clustered index IndMovSeq on #MovSeq (Cod_Empresa, Cod_Estoque, Cod_Produto, Seq); " & _
" SELECT M.Cod_Empresa, M.Cod_Estoque, M.Cod_Produto, P.Descricao," & _
" Estoque= case when M.Seq=1 then E.Qtde_Estoque else (E.Qtde_Estoque - (SELECT sum(Mi.Qtde) from #MovSeq as Mi " & _
" Where Mi.Cod_Empresa = M.Cod_Empresa And Mi.Cod_Estoque = M.Cod_Estoque And Mi.Cod_Produto = M.Cod_Produto and Mi.Seq < M.Seq)) end " & _
" from #MovSeq as M inner join " & _
" Estoque as E on M.Cod_Empresa=E.Cod_Empresa and M.Cod_Estoque=E.Cod_Estoque and M.Cod_Produto=E.Cod_Produto inner join " & _
" Produtos as P on M.Cod_Empresa=P.Cod_Empresa and M.Cod_Estoque=P.Cod_Estoque and M.Cod_Produto=P.Cod_Produto " & _
" where Data_Mov < #Data_Fim " & _
" order by M.Cod_Empresa, M.Cod_Estoque, M.Cod_Produto, Seq desc; " & _
" drop table #MovSeq;"
the error appears 'invalid columm name' when run showing DataInicio as a reason
I know the error is in the assignment of the variable. but how to solve.
Thanks for the help...
Your type of code is very prone to SQL Injection attacks...
Are you escaping the variable values correctly? A simple quote (') in one of the variables can change the SQL string completely...
You should consider using parameters to pass values instead of building SQL commands using string concatenation.

How to use distinct in mssql with many tables?

With the below SQL statement I get all information about a student as needed except for one problem which is duplicate records when in fact last entered record for each student needed only.
Student ID Year level Semester
20012-000001 20012-20013 1
20012-000001 20012-20013 2
20012-000001 20012-20013 3
20012-000001 20012-20013 4
20012-000001 20012-20013 5
sqlSTR = "SELECT tblStudent.StudentID AS '??? ??????' , (tblStudent.FirstName + ' ' + tblStudent.MiddleName + ' ' + tblStudent.GrandFatherName + ' ' + tblStudent.LastName) as '?????' ," & _
"tblStudent.Gender as '?????', tblStudent.Citizenship as '???????', tblStudent.Type as '??? ?????'," & _
"tblDepartment.DepartmentTitle as '?????', tblEnrolment.SchoolYear as '????? ????????',tblYearLevel.YearLevelTitle as '????? ???????', " & _
"'????'= CASE WHEN Len(tblGraduate.StudentID)<>12 THEN '???' ELSE ''End , " & _
"'???? ???'= CASE WHEN Len(tblDropped.StudentID)<>12 THEN '???' ELSE ''End , " & _
"'??????'= CASE WHEN tblStudent.Transferee ='True' THEN '???' ELSE ''End" & _
" FROM tblDropped RIGHT JOIN " & _
"(tblGraduate RIGHT JOIN " & _
"(tblDepartment RIGHT JOIN " & _
"(tblYearLevel RIGHT JOIN " & _
"(tblSection RIGHT JOIN " & _
"(tblStudent LEFT JOIN tblEnrolment " & _
"ON tblStudent.StudentID = tblEnrolment.StudentID) " & _
"ON tblSection.SectionID = tblEnrolment.SectionOfferingID) " & _
"ON tblYearLevel.YearLevelID = tblEnrolment.YearLevelID) " & _
"ON tblDepartment.DepartmentID = tblSection.DepartmentID) " & _
"ON tblGraduate.StudentID = tblStudent.StudentID) " & _
"ON tblDropped.StudentID = tblStudent.StudentID" & _
" " & sFilter & _
" ORDER BY tblStudent.StudentID DESC , tblYearLevel.YearLevelTitle ASC"
Add a Date Field to your table containing the records and filter by most recent. IF the table already has one include a WHERE clause by date?
If I understand your table correctly the last record is always in the last semester, if you know the semester just do a UNIQUE keyword for the Student_ID