MSSQL INNER JOIN WHERE Clause - sql

The following SQL Query finds orders matching certain requirements and then creates a new order (InvNum) with the invoice lines (_btblInvoiceLines) at this stage it has only created basic information.
DECLARE #gid varchar(50) SELECT #gid = newid()
INSERT INTO InvNum (DocType,DocState,AccountID,ucIDSOrdTempInvID)
SELECT 4,1,AccountID,#gid
FROM (SELECT DISTINCT AccountID
FROM InvNum
WHERE ubIDSOrdConsolOrder = '1'
AND DocState = '1'
AND DocType <> '5') A
INSERT INTO _btblInvoiceLines (iInvoiceID, iStockCodeID, fQuantity)
SELECT AutoIndex, iStockCodeID, qty
FROM (SELECT AutoIndex, iStockCodeID, qty
FROM (SELECT AutoIndex,AccountId,ucIDSOrdTempInvID
FROM InvNum
WHERE ucIDSOrdTempInvID = #gid) T1
INNER JOIN (SELECT B.iStockCodeID,A.AccountID,sum(B.fQuantity) AS qty
FROM (SELECT *
FROM InvNum
WHERE ubIDSOrdConsolOrder = '1'
AND DocState = '1'
AND DocType <> '5') A
INNER JOIN (SELECT *
FROM _btblInvoiceLines) B ON A.AutoIndex = B.iInvoiceID
GROUP BY iStockCodeID, AccountID) T2 ON T1.AccountId = T2.AccountID) T3
After this the InvNum columns are all updated, this works fine. My issue is with the following, which is updating the _btblInvoiceLines of the new order and new lines with that of the old orders, that which matches: WHERE ubIDSOrdConsolOrder = '1' AND DocState = '1' AND DocType <> '5'
This FROM clause is what is incorrect:
SELECT D1.*
FROM (SELECT A.*
FROM _btblInvoiceLines A
INNER JOIN (SELECT max(idInvoiceLines) as idInvoiceLines, iStockCodeID
FROM _btblInvoiceLines
GROUP BY iStockCodeID) B ON A.idInvoiceLines = B.idInvoiceLines) D1
INNER JOIN (SELECT *
FROM _btblInvoiceLines I1
INNER JOIN (SELECT accountid,autoindex,ucIDSOrdTempInvID
FROM InvNum
WHERE ucIDSOrdTempInvID = #gid) I2 ON I1.iInvoiceID = I2.AutoIndex) D2 ON D1.iStockCodeID = D2.iStockCodeID
WHERE _btblInvoiceLines.idInvoiceLines = D2.idInvoiceLines
I'm at a lost of how to make D1.* pull out the information from the last original _btblInvoiceLines that was added into the new orders, D2 . The only way I believe I can do this is using the following SELECT DISTINCT AccountID,ubIDSOrdConsolOrder FROM InvNum WHERE ubIDSOrdConsolOrder = '1' AND DocState = '1' AND DocType <> '5' but I'm at a loss of how to put this in correctly. Sorry if this is a simple question, but I have been looking and attempting to resolve this issue for 2 days now without any luck.
Thank you.

I had the INNER JOIN in the wrong order. I did the following and this now works correctly:
SELECT D1.*
FROM (SELECT DISTINCT AccountID, AutoIndex FROM InvNum WHERE ubIDSOrdConsolOrder = '1' AND DocState = '1' AND DocType <> '5') A1
INNER JOIN (SELECT * FROM _btblInvoiceLines) D1 ON A1.AutoIndex = D1.iInvoiceID----
INNER JOIN (SELECT max(idInvoiceLines) as idInvoiceLines, iStockCodeID FROM _btblInvoiceLines GROUP BY iStockCodeID) I1 ON D1.iStockCodeID = I1.iStockCodeID
INNER JOIN (SELECT * FROM _btblInvoiceLines I1 INNER JOIN (select accountid,autoindex,ucIDSOrdTempInvID FROM InvNum where ucIDSOrdTempInvID = #gid) I2 ON I1.iInvoiceID=I2.AutoIndex) D2 ---- #gid
ON D1.iStockCodeID=D2.iStockCodeID
WHERE _btblInvoiceLines.idInvoiceLines = D2.idInvoiceLines

Related

SELECT subquery for dates in BETWEEN WHERE clause

I want to use dates from a different table in the BETWEEN inside the WHERE clause.
How can I inject the dates? The query below works, but is much slower than using plain dates.
I've tried rewriting the query in numerous ways, as well as use CTEs, to no avail.
Is there a way to make this work faster?
select *
from (
select
ti.*,
si.anvat as vat,
cast(si.acName as nvarchar(255)) productNameOriginal,
cast(su.acName as nvarchar(255)) unit,
cast(ss.acName2 as nvarchar(255)) supplier,
historyStart,
historyEnd
from tenderItem ti
left join the_setitem si on si.acIdent = ti.sku
left join tHE_SetUM su on su.acUM = si.acUM
left join tHE_SetSubj ss on ss.acSubject = si.acSupplier
left join tender t on t.id = ti.tenderId
where tenderId = 1
) t1
left join (
select
acident sku,
sum(anQty) historyQuantity,
round(max(anRTPrice), 2) historyPrice
from the_moveitem mi
left join the_move m on m.ackey = mi.ackey
where
m.acDocType in (
'3000'
'3050'
)
and m.acreceiver = '11111'
and m.addate
between (select historyStart from tender where id = 1) -- <------ THIS PART
and (select historyEnd from tender where id = 1) -- <------ THIS PART
group by acident
) history on history.sku = t1.sku
Managed to solve it by using variables.
DECLARE #historyStart DATE;
SET #historyStart = (select historyStart from tender where id = #tenderId);
DECLARE #historyEnd DATE;
SET #historyEnd = (select historyEnd from tender where id = #tenderId);
--
and m.addate between #historyStart and #historyEnd

Trying to run a query in Information Design Tool in SAP (using mssql database)

WITH c AS
(SELECT A.QuestionHdrKey AS QuestionHdrKey1,
A.DivisionKey AS DivisionKey1,
COUNT(1) AS QCount
FROM Mobile.QuestionLocationMap A WITH (NOLOCK)
INNER JOIN Mobile.Question b WITH (NOLOCK) ON A.QuestionKey = b.PKey
WHERE A.QuestionHdrKey = 200305685377000000
GROUP BY A.QuestionHdrKey,
A.DivisionKey),
d AS
(SELECT a.QuestionHdrKey,
a.QuestionKey,
a.DivisionKey,
a.InvDate,
a.HdrKey,
ROW_NUMBER() OVER (PARTITION BY a.DivisionKey,
a.invdate,
a.HdrKey
ORDER BY a.QuestionKey) AS RowId
FROM mobile.StatusReport a WITH (NOLOCK)
INNER JOIN mobile.Question b WITH (NOLOCK) ON a.QuestionKey = b.PKey
AND b.QuestionType = 'rate'
AND InputType = 'numeric'
WHERE a.QuestionHdrKey = '200305685377000000'
GROUP BY a.QuestionHdrKey,
a.DivisionKey,
a.HdrKey,
a.InvDate,
a.QuestionKey)
SELECT a.DivisionKey,
a.InvDate AS ModifiedDate,
a.QuestionHdrKey,
a.HdrKey,
COUNT(DISTINCT a.QuestionKey) AS QuestionKey,
SUM(CAST(a.Value AS int)) AS value,
SUM(b.Rate) AS RATE
--case when a.invdate between '2020-05-09' and '2022-03-31' then case when then case when cast(Value as int)*5>5 then 5 else cast(Value as int)*5 end else cast(Value as int) end as value,c.QCount
FROM mobile.StatusReport a WITH (NOLOCK)
INNER JOIN mobile.Question b WITH (NOLOCK) ON a.QuestionKey = b.PKey
AND b.QuestionType = 'rate'
AND InputType = 'numeric'
INNER JOIN c WITH (NOLOCK) ON a.DivisionKey = c.DivisionKey1
INNER JOIN d WITH (NOLOCK) ON a.HdrKey = d.HdrKey
AND a.QuestionKey = d.QuestionKey
WHERE a.QuestionHdrKey = '200305685377000000'
--and a.HdrKey='210305757994230000'
AND d.RowId <= c.QCount
GROUP BY a.DivisionKey,
a.InvDate,
a.QuestionHdrKey,
a.HdrKey,
c.QCount;
I have this table queried in PowerBI which generates the below table:
The SQL is validated successfully in Information Design Tool but when trying to view its values, it shows an error in the code. How do I work around this?
Alright, after figuring out that "with as" doesn't work outside of the select function in the IDS, I've ditched the aliases and used sub-queries.
select HdrKey,a.DivisionKey,InvDate,RowId ,count(b.QuestionKey) as QCount,qCOUNT_,[value],POINT
from
(select distinct a.HdrKey,a.DivisionKey, a.InvDate, ROW_NUMBER() OVER(PARTITION BY QuestionHdrKey, DivisionKey, a.InvDate ORDER BY a.InvDate) AS RowId,
sum(cast([value] as int)) AS [value], COUNT(DISTINCT A.QuestionKey) AS qCOUNT_, SUM(B.Rate) AS POINT
from NominInventory.mobile.StatusReport a with(nolock)
inner join NominInventory.mobile.Question b with(nolock) on a.QuestionKey=b.PKey and B.QuestionType = 'rate' and InputType='numeric'
where a.QuestionHdrKey='200305685377000000'
GROUP BY a.HdrKey,a.DivisionKey, a.InvDate,QuestionHdrKey
) a
inner join NominInventory.Mobile.QuestionLocationMap b with(nolock) on a.DivisionKey=b.DivisionKey and b.QuestionHdrKey = '200305685377000000'
group by HdrKey,a.DivisionKey,InvDate,RowId,qCOUNT_,[value],POINT
having a.RowId<=count(b.QuestionKey)

SQl Error : Each GROUP BY expression must contain at least one column that is not an outer reference [duplicate]

This question already has answers here:
Each GROUP BY expression must contain at least one column that is not an outer reference
(8 answers)
Closed 6 years ago.
I get this error
Each GROUP BY expression must contain at least one column that is not an outer reference
while running this query:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN
#tmpInstallParts_Temp installpartdetails ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END
) = 1
INNER JOIN
partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN
partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN
partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y' AND
ima.ipp_ID IN (SELECT ipp.ipp_id
FROM partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp ON (ipp.ipp_id = tmp.InstallingPartIPPId OR
(CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1
)
GROUP BY
ima.ipp_id
Can someone help me?
This is the text of the query from the first revision of the question.
In later revisions you removed the last closing bracket ) and the query became syntactically incorrect. You'd better check and fix the text of the question and format the text of the query, so it is readable.
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
GROUP BY
ima.ipp_id
)
With this formatting it is clear now that there is a subquery with GROUP BY.
Most likely it is just a typo: you meant to write GROUP BY ipp.ipp_id instead of GROUP BY ima.ipp_id.
If you really wanted to have the GROUP BY not in a subquery, but in the main SELECT, then you misplaced the closing bracket ) and the query should look like this:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
)
GROUP BY
ima.ipp_id
In any case, proper formatting of the source code can really help.
Group By ima.ipp_id
should be applicable to outer query. Because of incorrect placement of '(' it was applying to inner query.
Now after correcting the query,it's working fine without any issues.
Final Query is :
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END ) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END ) =1)
)
GROUP BY ima.ipp_id
Thank you all.

SQL Select Statement SubSelect not working correct

I have 2 SQL Select Queries which I need in two seperare columns. The code I have just now does exactly that, but it also gives 2 nulls. Here is my code :
Select a.Budget, b.Actual_Income FROM
(Select sum(subscriptions.Bill_Amount) as Budget
From imis.dbo.Name Name INNER JOIN imis.dbo.Subscriptions Subscriptions ON Name.ID=Subscriptions.ID
Where Member_Type = 'MM' and Name.Status = 'a' and Product_Code = 'Annual' and Subscriptions.Status = 'a') AS a
FULL JOIN
(SELECT sum(Amount * -1) as Actual_Income
FROM imis.dbo.Name Name INNER JOIN imis.dbo.Trans Trans ON Name.ID=Trans.BT_ID
WHERE PRODUCT_CODE ='ANNUAL' and Transaction_Date >= '21/10/2013' and Batch_Num <> 'DD131031-3') AS b
ON a.Budget = b.Actual_Income
This Is what It returns
Budget Actual_Income
6367005.00 NULL
NULL 665712.37
Any help is much appreciated!
You have a FULL JOIN. Change it to INNER JOIN.
Check this link for better understanding SQL JOINS
If your results were meant to be as the following:
Budget Actual_Income
6367005.00 665712.37
Then you can do subselect or aggregate:
SubSelect:
Select (Select sum(subscriptions.Bill_Amount) as Budget
From imis.dbo.Name Name INNER JOIN imis.dbo.Subscriptions Subscriptions ON Name.ID=Subscriptions.ID
Where Member_Type = 'MM' and Name.Status = 'a' and Product_Code = 'Annual' and Subscriptions.Status = 'a') Budget,
(SELECT sum(Amount * -1) as Actual_Income
FROM imis.dbo.Name Name INNER JOIN imis.dbo.Trans Trans ON Name.ID=Trans.BT_ID
WHERE PRODUCT_CODE ='ANNUAL' and Transaction_Date >= '21/10/2013' and Batch_Num <> 'DD131031-3') as Actual_Income
aggregate:
Select MAX(a.Budget), MAX(b.Actual_Income) FROM
(Select sum(subscriptions.Bill_Amount) as Budget
From imis.dbo.Name Name INNER JOIN imis.dbo.Subscriptions Subscriptions ON Name.ID=Subscriptions.ID
Where Member_Type = 'MM' and Name.Status = 'a' and Product_Code = 'Annual' and Subscriptions.Status = 'a') AS a
FULL JOIN
(SELECT sum(Amount * -1) as Actual_Income
FROM imis.dbo.Name Name INNER JOIN imis.dbo.Trans Trans ON Name.ID=Trans.BT_ID
WHERE PRODUCT_CODE ='ANNUAL' and Transaction_Date >= '21/10/2013' and Batch_Num <> 'DD131031-3') AS b

Date comparison function in SQL Server

I am trying to display records which are created after Oct 1 2010. But my query doesn't seem to work. It also display records from 2004 - Sept 2010 which is not wanted.
What is wrong with the query below?
select Distinct app.app_id,
(convert(varchar, creation_date,101) + ' ' + convert(varchar,creation_date ,108)) as creation_date,
dbo.oea_fn_get_amc_mem_name(app.app_id,primary_msn,getdate(), 'EN', 30000) PIName,
dbo.oea_fn_get_pid_countyname(app.app_id,primary_msn,'OC')as PIpid,
primary_msn,
zip,
home_tel,
work_tel,
work_extn,
other_contact,
other_ext,
cell_tel,
dbo.oea_fn_get_amc_mem_name(app.app_id,mem.msn,getdate(), 'EN', 30000)as Kname,
dbo.oea_fn_get_pid_countyname(app.app_id,mem.msn,'OC')as Knamepid,
mem.msn as Kmsn,
(select count(reminder_id) from reminders (nolock) where app_id=app.app_id) as reminder
from app_application app (nolock)
inner join app_member mem with (nolock) on app.app_id=mem.app_id
--left outer join Oea_App_Program_Disposition disp with (nolock) on mem.app_id = disp.app_id and mem.msn=disp.msn
inner join app_address aadd with (nolock) on app.app_id=aadd.app_id
--inner join app_calc_results calc with (nolock) on mem.app_id=calc.app_id and calc.msn=mem.msn
left outer join app_member_benefits ben with (nolock) on mem.app_id = ben.app_id and mem.msn=ben.msn
where
isnull(mem.coverage_required,0) = 1
and app.app_status = 's'
and ben.ins_end_date < getdate()
and app.client_id = 30000
and app.app_id not in (select app_id from app_renewal)
and (mem.msn in (select calc.msn from app_calc_results calc
inner join app_application app on calc.app_id = app.app_id and calc.prog_id = 'CK' and calc.opt_out = 1))
and (mem.msn in (select msn from app_calc_results where app_id=app.app_id and status not in ('A','X')))
or (mem.msn in (select msn from Oea_App_Program_Disposition where app_id=app.app_id and disp_status not in ('A','P')) )
and app.creation_date >= '10/01/2010'
Thanks for all the help.
You probably want this:
and (
(mem.msn in (select calc.msn from app_calc_results calc
inner join app_application app on calc.app_id = app.app_id and calc.prog_id = 'CK' and calc.opt_out = 1))
or (mem.msn in (select msn from app_calc_results where app_id=app.app_id and status not in ('A','X')))
or (mem.msn in (select msn from Oea_App_Program_Disposition where app_id=app.app_id and disp_status not in ('A','P')) )
)
and app.creation_date >= '10/01/2010'
The problem is with the logic behind the or in the where clause.
As others have stated, the problem is likely the Or clause in the Where clause. In effect, your query is:
Select ...
From ..
Where (A And B And C
And D And E
And F And G
And app.creation_date >= '10/01/2010'
)
Or mem.msn In (
Select msn
From Oea_App_Program_Disposition
Where app_id=app.app_id
And disp_status not in ('A','P')
)
Thus, if for any row, if the Or is true, the rest of the "Ands" are ignored. I would assume that the Or is supposed to be paired with one of the And clauses.