Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
WITH
cust AS
(SELECT DISTINCT
C.swCustomerId AS EnduserId,
A.AssetID AS asset,
suite.ctName AS Product
FROM ReplicaCADS.dbo.TransactionHeader TH WITH (NOLOCK)
INNER JOIN ReplicaCRMDB.dbo.SW_CUSTOMER C WITH (NOLOCK) ON C.swCustomerId = TH.EndUserCustomerId
INNER JOIN ReplicaCADS.dbo.Asset A WITH (NOLOCK) ON TH.TransactionId = A.TransactionId
AND A.Status = 'Active'
INNER JOIN ReplicaCADS.dbo.AssetComponent AC WITH (NOLOCK) ON AC.AssetId = A.AssetId
AND AC.PrimaryFlag = 1
AND AC.Status = 'Active'
INNER JOIN ReplicaCADS.dbo.MaintenanceProgram MP WITH (NOLOCK) ON MP.AssetId = A.AssetId
AND IsLatest = 1
AND MP.Status = 'Active'
AND MP.EndDate <> '2099-12-31 00:00:00.000'
AND MP.MaintenanceType = 'Core'
INNER JOIN ReplicaCRMDB.dbo.[ct_Product_Suite] suite WITH (NOLOCK) ON suite.ctSuiteID = A.ProductSuiteID
AND suite.cTName LIKE 'DaaS'
INNER JOIN Salesforce.[dbo].[Apttus__APTS_Agreement__c] agr ON agr.Vantive_Org_ID__c = C.ctOrgId
AND Apttus__Status__c = 'Activated'
AND Agreement_Type__c = 'Licensing'
AND agr.Account_Geo__c LIKE 'APAC'
WHERE NOT EXISTS (SELECT 1
FROM salesforce..Priority_Customer__c pr
WHERE pr.Account_Org_Id__c = C.CtOrgId)
AND NOT EXISTS (SELECT 1
FROM ReplicaTransactionData..[Transaction] TN
WHERE TN.CustomerId = C.swCustomerId
AND Status = 'Pending'
AND QuoteType IS NULL)
AND NOT EXISTS (SELECT 1
FROM [Salesforce]..Large_Customer__c LDC
WHERE LDC.Org_ID__c = C.ctOrgId)
AND NOT EXISTS (SELECT 1
FROM [Salesforce].dbo.Account sac
WHERE sac.Org_ID__C = C.ctOrgId
AND High_Touch_Account__C = 'true')
AND NOT EXISTS (SELECT 1
FROM salesforce..Priority_Customer__c pr
WHERE pr.Account_Org_Id__c = C.ctOrgId)
AND NOT EXISTS (SELECT 1
FROM Salesforce..Asset_Maintenance_Program__c
WHERE frmAccount_Org_ID__c = C.ctOrgId
AND Maintenance_Type__c IN ('Advanced'))
AND EXISTS (SELECT 1
FROM ReplicaCADS..AssetpricingData AP
WHERE AP.AssetId = A.AssetId))
SELECT TOP 1
P.swLogin AS LoginId
FROM cust
INNER JOIN ReplicaCRMDB.dbo.SW_PERSON P WITH (NOLOCK) ON P.swCustomerId = EnduserId
AND P.swStatus = 'Current'
AND SWLogin IS NOT NULL
AND P.ctLocale = 'en-US'
INNER JOIN ReplicaCRMDB.dbo.CT_CONTACT_TYPE Contact WITH (NOLOCK) ON Contact.swContactId = P.swPersonId
INNER JOIN ReplicaCRMDB.dbo.CT_MC_USERS MCUsers ON MCUsers.swPersonID = P.swPersonId
AND (MCUsers.ctPassword = '32CA9FC1A0F5B6330E3F4C8C1BBECDE9BEDB9573'
OR MCUsers.ctPassword = '')
ORDER BY NEWID();
When trying to use both the below condition together its taking a long time
AND NOT EXISTS (SELECT 1
FROM Salesforce..Asset_Maintenance_Program__c
WHERE frmAccount_Org_ID__c = C.ctOrgId
AND Maintenance_Type__c IN ('Advanced'))
AND EXISTS (SELECT 1
FROM ReplicaCADS..AssetpricingData AP
WHERE AP.AssetId = A.AssetId)
Can you please help me in someway tweaking the above query to get the result in quick time
This can be massively helped by understanding how SQL works. But I would recommend that you remove most of the text fields in the joins, and using their int values instead that I suppose exist.
For instance - High_Touch_Account__C = 'true', this should probably be stored as a BIT inside of the DB, and as such, 1 or 0 would be the way to go, not 'true'. Similarily the Status = 'Active' should probably be replaced with using the int value for 'Active'.
Regarding the and not exists, I would probably create a temporary table at the start that gathers all of the things that you do not want in there, then simply do a left join and then "where join is null" basically. This could replace 25% of your code.
NOLOCK might also be something that you should look into.
If you upload the files with the data, It would be easier however to give you a reply on the most optimal way to do this, but as it sits, we've got no idea of what data exists.
Related
I am trying write a query to create a report and for the report, I need to get the manager of the user who created a form on our system. Because the system is old and changed a lot, there is no easy way to get the manager of the user or get their manager from the time when they created the form. So, the person before me created a function for the job but it is costly. It takes way too long to get a result from the function fn_getUserMan. I want to call the function once and then use the result on my other selections as a variable and because it is dependent on Frm, I cannot take it out of the sub-query and have it on the main query and set it on a local variable and sql wont let me set the variable on the sub-query.
So my question is this: Is it possible to use FnMAN in my next selection as i tried in the query. It says Invalid column name 'FnMAN'. when i try it like in the query.
In the code block, it seems like i need it only twice but i actually need it a lot more. I need to check the result and if its some person A, i need to make it some person B like i did with John and Jane. So i really need to make this faster.
select *,(--More selection--)
from
(select
--
--Some selection of 10s of columns
--
(select dbo.fn_getUserMAN((
select M.txtPerson from Frm (nolock) Fm
JOIN FLOWDOCUMENTS(nolock) FD ON Fm.ID = FD.FILEPROFILEID
JOIN FLOWREQUESTS(nolock) FR on FD.PROCESSID = FR.PROCESSID
JOIN MdlFrm (nolock) M on M.ID = FR.EVENTFORMID
where FR.EVENTFORMID !=-1 and F.FrmNo = Fm.FrmNo))
) AS 'FnMAN',
(SELECT TOP 1 (
CASE WHEN
(select txtPerson from Frm_Info (nolock) as BB
inner join FLOWREQUESTS(nolock) FQ on BB.ID = FQ.EVENTFORMID
and FQ.PROCESSID = FD.PROCESSID) is not null
or
(select txtPerson from Frm_Info (nolock) as BB
inner join FLOWREQUESTS(nolock) FQ on BB.ID = FQ.EVENTFORMID
and FQ.PROCESSID = FD.PROCESSID) !=''
THEN
CASE WHEN FnMAN = 'John Doe'
THEN 'Jane Doe'
--More checks and switches on managers
ELSE FnMAN END
WHEN F.txtManager IS NOT NULL THEN F.txtManager END))
from Frm (NOLOCK) F
INNER JOIN FLOWDOCUMENTS(NOLOCK) FD ON FD.FILEPROFILEID = F.ID
INNER JOIN LIVEFLOWS(NOLOCK) LF ON LF.ID = FD.PROCESSID
INNER JOIN FLOWSTATUSES(NOLOCK) FS ON FS.PROCESS = LF.PROCESS AND FS.VERSION =LF.FLOWVERSION AND FS.STATUS = LF.STATUS
WHERE LF.DELETED = 0 and F.FrmNo IS NOT NULL and F.FrmNo != '') T
I found the solution with LEFT JOIN and added a new column to use as a result of FnMAN. I dont know whether or not this is a healthy way of having a a solution but it works.
select *,(--More selection--)
from
(select
--
--Some selection of 10s of columns
--
(SELECT TOP 1 (
CASE WHEN
(select txtPerson from Frm_Info (nolock) as BB
inner join FLOWREQUESTS(nolock) FQ on BB.ID = FQ.EVENTFORMID
and FQ.PROCESSID = FD.PROCESSID) is not null
or
(select txtPerson from Frm_Info (nolock) as BB
inner join FLOWREQUESTS(nolock) FQ on BB.ID = FQ.EVENTFORMID
and FQ.PROCESSID = FD.PROCESSID) !=''
THEN
CASE WHEN FnMAN.MAN = 'John Doe'
THEN 'Jane Doe'
--More checks and switches on managers
ELSE FnMAN.MAN END
WHEN F.txtManager IS NOT NULL THEN F.txtManager END))
from Frm (NOLOCK) F
INNER JOIN FLOWDOCUMENTS(NOLOCK) FD ON FD.FILEPROFILEID = F.ID
INNER JOIN LIVEFLOWS(NOLOCK) LF ON LF.ID = FD.PROCESSID
INNER JOIN FLOWSTATUSES(NOLOCK) FS ON FS.PROCESS = LF.PROCESS AND FS.VERSION =LF.FLOWVERSION AND FS.STATUS = LF.STATUS
LEFT JOIN (
(select Fm.FormID, dbo.fn_getUserMAN(M.txtPerson) MAN
from Frm (nolock) Fm
JOIN FLOWDOCUMENTS(nolock) FD ON Fm.ID = FD.FILEPROFILEID
JOIN FLOWREQUESTS(nolock) FR on FD.PROCESSID = FR.PROCESSID
JOIN MdlFrm (nolock) M on M.ID = FR.EVENTFORMID
where FR.EVENTFORMID !=-1)
) AS 'FnMAN' on Fm.FormID = F.FormID,
WHERE LF.DELETED = 0 and F.FrmNo IS NOT NULL and F.FrmNo != '') T
Could anyone help me speed this query up? It currently take 17 minutes to run but does return the correct data and it populates a subform in MS Access. Functions in the rest of the VBA are declared as long to try to speed up more.
Here's the full query:
SELECT lots of things
FROM (((((((((((((((ngstest
INNER JOIN patients
ON ngstest.internalpatientid = patients.internalpatientid)
INNER JOIN referral
ON ngstest.referralid = referral.referralid)
INNER JOIN checker
ON ngstest.bookby = checker.check1id)
INNER JOIN ngspanel
ON ngstest.ngspanelid = ngspanel.ngspanelid)
LEFT JOIN ngspanel AS ngspanel_1
ON ngstest.ngspanelid_b = ngspanel_1.ngspanelid)
INNER JOIN status
ON ngstest.statusid = status.statusid)
INNER JOIN dbo_patient_table
ON patients.patientid = dbo_patient_table.patienttrustid)
LEFT JOIN dna
ON ngstest.dna = dna.dnanumber)
INNER JOIN status AS status_1
ON patients.s_statusoverall = status_1.statusid)
LEFT JOIN gw_gendertable
ON dbo_patient_table.genderid = gw_gendertable.genderid)
LEFT JOIN ngswesbatch
ON ngstest.wesbatch = ngswesbatch.ngswesbatchid)
LEFT JOIN checker AS checker_1
ON ngstest.check1id = checker_1.check1id)
LEFT JOIN checker AS checker_2
ON ngstest.check2id = checker_2.check1id)
LEFT JOIN checker AS checker_3
ON ngstest.check3id = checker_3.check1id)
LEFT JOIN ngspanel AS ngspanel_2
ON ngstest.ngspanelid_c = ngspanel_2.ngspanelid)
LEFT JOIN checker AS checker_4
ON ngstest.check4id = checker_4.check1id
WHERE ((ngstest.referralid IN
(SELECT referralid FROM referral
WHERE grouptypeid = 14)
AND ngstest.ngstestid IN
(SELECT ngstest.ngstestid
FROM ngsanalysis
INNER JOIN ngstest
ON ngsanalysis.ngstestid = ngstest.ngstestid
WHERE ngsanalysis.pedigree = 3302) )
AND status.statusid = 1202218800)
ORDER BY ngstest.priority,
ngstest.daterequested;
The two nested queries are strings from elsewhere in the code so are called in the vba as " & includereferralls & " And " & ParentsStatusesFilter & "
They are:
ParentsStatusesFilter = "NGSTest.NGSTestID in
(SELECT NGSTest.NGSTestID
FROM NGSAnalysis
INNER JOIN NGSTest
ON NGSAnalysis.NGSTestID = NGSTest.NGSTestID
WHERE NGSAnalysis.Pedigree IN (3302,3303,3304)"
And
includereferrals = "NGSTest.ReferralID
(SELECT referralid FROM referral WHERE referral.grouptypeid = 14)"
The query needs to remain readable (and therefore editable) so can't use things like Distinct, Group By or contain any Unions. Have tried Exists instead of In for the nested queries but that stops it from actually filtering the results.
WHERE EXISTS (SELECT NGSTest.NGSTestID
FROM NGSAnalysis
INNER JOIN NGSTest
ON NGSAnalysis.NGSTestID = NGSTest.NGSTestID
WHERE NGSAnalysis.Pedigree IN (3302,3303,3304)
So the exist clause you have there isn't tied to the outer query which would run similar to just added 1 = 1 to the where clause. I took your where clause and converted it. It should look something like this...
WHERE EXISTS (
SELECT referralid
FROM referral
WHERE grouptypeid = 14 AND ngstest.referralid = referral.referralid)
AND EXISTS (
SELECT ngsanalysis.ngstestid
FROM ngsanalysis
WHERE ngsanalysis.pedigree IN (3302,3303,3304) AND ngstest.ngstestid = ngsanalysis.ngstestid
)
AND status.statusid = 1202218800
Adding exists will speed it up a bit, but the the bulk of the slowness is the left joins. Access does not handle the left joins as well as SQL Server does. Change all your joins to inner joins and you will see the query runs very fast. This is obviously not ideal since some relationships are optional. What I have done to get around this is add a default record that replaces a null relationship.
Here is what that looks like for you: In the checker table you could add a record that represents a null value. So put a record into the checker table with check1id of -1 or 0. Then default check1id, check2id, check3id on ngstest to -1 or 0. You will need to do that type of thing for all tables you need to left join on.
I have two tables Question and Answers. Question table have column 'QuestionType' and its value is either 1 if question is of type text and 2 if question has pre-define answer options for example radio, drop-down
I am trying T-SQL where I need only answers against question if answer has value. now for QuestionType if value is null or empty then that is mean no answer which will be fillter out but for QuestionType 2, it will always null even if there is answer because there is another table holding that information.
I need Answer where value exist but also also questionType of 2 even with Null value in Answer
i did in following but condition rule out of questionType 2 which I don't want
FROM [dbo].[MyTable] AS sur
INNER JOIN [dbo].[SurveyQuestions] AS surQus ON sur.Id = surQus.SurveyId
INNER JOIN [dbo].[Questions] AS qus ON surQus.QuestionId = qus.Id
LEFT JOIN [dbo].[Responses] AS res ON res.SurveyId = sur.Id
LEFT JOIN [dbo].[Answers] AS ans ON res.Id = ans.ResponseId AND qus.Id = ans.QuestionId
LEFT JOIN [dbo].[AnswerOptions] AS ansOpt ON ans.Id = ansOpt.AnswerId
LEFT JOIN [dbo].[QuestionOptions] AS qusOpt ON ansOpt.QuestionOptionId = qusOpt.Id
WHERE con.Id = '00000011-0013-4D34-8888-7E7189CA348U'
AND (qus.QuestionType ='1' AND ans.Value IS NOT NULL ) //???????? NEED HELP HERE
If I understand your question you need an OR statement, with each set of conditions in their own set of parenthesis, surrounded by one main set of parenthesis.
FROM [dbo].[MyTable] AS sur
INNER JOIN [dbo].[SurveyQuestions] AS surQus ON sur.Id = surQus.SurveyId
INNER JOIN [dbo].[Questions] AS qus ON surQus.QuestionId = qus.Id
LEFT JOIN [dbo].[Responses] AS res ON res.SurveyId = sur.Id
LEFT JOIN [dbo].[Answers] AS ans ON res.Id = ans.ResponseId AND qus.Id = ans.QuestionId
LEFT JOIN [dbo].[AnswerOptions] AS ansOpt ON ans.Id = ansOpt.AnswerId
LEFT JOIN [dbo].[QuestionOptions] AS qusOpt ON ansOpt.QuestionOptionId = qusOpt.Id
WHERE con.Id = '00000011-0013-4D34-8888-7E7189CA348U'
AND (
(qus.QuestionType ='1' AND ans.Value IS NOT NULL )
OR
(qus.QuestionType ='2')
)
I am fairly new to SQL and I'm having trouble finding out how to fix this error. I understand that I'll get the error because I'm pulling the same column name twice from the same table, so I've created different aliases for the tables.
What I am trying to do is update a table in my database using a query to pull data from a linked server.
Here is a sample:
UPDATE [Database].dbo.T1
SET
T1.Status = item.Status,
T1.CategoryA = c.DESC_TEXT,
T1.CategoryB = d.DESC_TEXT
FROM
(SELECT c.DESC_TEXT, d.DESC_TEXT
inner join CSM_CODE c ON c.DESC_CD = item.ParCat and c.DESC_TYPE = 'PARCAT'
inner join CSM_CODE d ON d.DESC_CD = item.ChCat and d.DESC_TYPE = 'CHCAT'
WHERE
T1.Status = 'NEW')) A
WHERE [Database].dbo.T1.ID = A.ID
Here is my exact error:
The column 'DESC_TEXT' was specified multiple times for 'A'
So I don't know what to do about the aliases in my subquery for this update. Any help is appreciated!
Thank you all for helping figure this out. I now know why I was still receiving errors. Once I created the alias within my sub query, I had failed to update that alias in the SET.
UPDATE [database].dbo.T1
SET
[STATUS] = A.[STATUS],
[Scrum Team] = A.team_name,
[Parent Category] = A.prodparcat,
[Child Category] = A.prodcat
FROM
(SELECT
item.SEQ_ID,
item.STATUS,
c.DESC_TEXT prodparcat,
d.DESC_TEXT prodcat
FROM item
inner join csm_code c ON c.DESC_CD = item.parent_cat_cd and c.DESC_TYPE = 'PRODPARCAT'
inner join CSM_CODE d ON d.DESC_CD = item.prod_cat and d.DESC_TYPE = 'PRODCAT'
WHERE
item.STATUS = 'NEW' ) A
WHERE
[database.dbo.T1.[external ID] = A.SEQ_ID
It's also important to note that I was querying a linked server which required some creativity with my alias. Overall a great learning experience.
Thanks again!
Instead of FROM it should be a update-join construct like below. Also use column alias name for the duplicated columns.
UPDATE [Database].dbo.T1
SET
T1.Status = item.Status,
T1.CategoryA = A.cdesk,
T1.CategoryB = A.ddesk
JOIN
(SELECT c.DESC_TEXT as cdesk, d.DESC_TEXT as ddesk
FROM item
inner join CSM_CODE c ON c.DESC_CD = item.ParCat and c.DESC_TYPE = 'PARCAT'
inner join CSM_CODE d ON d.DESC_CD = item.ChCat and d.DESC_TYPE = 'CHCAT'
WHERE T1.Status = 'NEW')) A
ON [Database].dbo.T1.ID = A.ID
You are combining a column named DESC_TEXT from two different tables into a single table, namely A in your case. In that case, you have to give these two columns different names, like DESC_TEXT_c and DESC_TEXT_d and update T1 accordingly.
I suspect you want:
UPDATE T1
SET Status = item.Status,
CategoryA = c.DESC_TEXT,
CategoryB = d.DESC_TEXT
FROM [Database].dbo.T1 T1 JOIN
CSM_CODE c
ON c.DESC_CD = T1.ParCat and c.DESC_TYPE = 'PARCAT' JOIN
CSM_CODE d
ON d.DESC_CD = item.ChCat and d.DESC_TYPE = 'CHCAT'
WHERE T1.Status = 'NEW';
As written, your code has multiple syntax errors. The two references to DESC_TEXT in the subquery are the tip of the iceberg. I believe the above is the logic you want.
You have specified DESC_TEST twice with
c.DESC_TEXT, d.DESC_TEXT
Try renaming to.
c.DESC_TEXT category_a , d.DESC_TEXT category_b
You'll also need an id in A to join on.
An example to give you an idea.
UPDATE [Database].dbo.T1
SET
T1.Status = A.Status,
T1.CategoryA = A.CategoryA,
T1.CategoryB = A.CategoryB
FROM
(SELECT item.status, c.id, c.DESC_TEXT CategoryA, d.DESC_TEXT CategoryB
from item -- added after seeing the answer.
inner join CSM_CODE c ON c.DESC_CD = item.ParCat and c.DESC_TYPE = 'PARCAT'
inner join CSM_CODE d ON d.DESC_CD = item.ChCat and d.DESC_TYPE = 'CHCAT'
WHERE
T1.Status = 'NEW')) A
WHERE [Database].dbo.T1.ID = A.ID
Untested
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i have to count 1 column by two condition resulting 2 columns, grouped by another column. I'll show you:
SELECT cy.Name, COUNT(noa.GZ_Aparat_ID), COUNT(noa.GZ_Aparat_ID)
FROM GZ_Nominalizare_Aparat noa
INNER JOIN GZ_Nominalizare no ON (no.GZ_NOMINALIZARE_ID = noa.GZ_NOMINALIZARE_ID)
INNER JOIN GZ_AcordAcces aa ON (aa.GZ_ACORDACCES_ID = no.GZ_ACORDACCES_ID)
INNER JOIN GZ_Abonament ab ON (ab.GZ_ABONAMENT_ID = aa.GZ_ABONAMENT_ID)
INNER JOIN GZ_PunctConsum pc ON (pc.GZ_ABONAMENT_ID = ab.GZ_ABONAMENT_ID)
INNER JOIN GZ_IU iu ON (iu.GZ_PUNCTCONSUM_ID = pc.GZ_PUNCTCONSUM_ID)
LEFT OUTER JOIN C_BPartner_Location bplo ON (ab.C_BPartner_Location_ID = bplo.C_BPARTNER_LOCATION_ID)
LEFT OUTER JOIN C_Location lo ON (bplo.C_Location_ID = lo.C_Location_ID)
LEFT OUTER JOIN C_City cy ON (lo.C_City_ID = cy.C_City_ID)
GROUP BY cy.Name
Firt COUNT must contain the counts of noa.GZ_Aparat_ID where iu.GZ_DataPIF IS NULL
AND Second COUNT where iu.GZ_DataPIF IS NOT NULL
Not sure if my syntax is quite right for oracle but it's not too dissimilar.
SELECT cy.Name,
SUM(CASE WHEN noa.GZ_Aparat_ID is NULL THEN 0
WHEN noa.GZ_Aparat_IDis NOT NULL THEN 1
END) as COUNTNONNULL,
SUM(CASE WHEN noa.GZ_Aparat_ID is NULL THEN 1
WHEN noa.GZ_Aparat_ID is NOT NULL THEN 0
END) as COUNTNULL
FROM GZ_Nominalizare_Aparat noa
INNER JOIN GZ_Nominalizare no ON (no.GZ_NOMINALIZARE_ID = noa.GZ_NOMINALIZARE_ID)
INNER JOIN GZ_AcordAcces aa ON (aa.GZ_ACORDACCES_ID = no.GZ_ACORDACCES_ID)
INNER JOIN GZ_Abonament ab ON (ab.GZ_ABONAMENT_ID = aa.GZ_ABONAMENT_ID)
INNER JOIN GZ_PunctConsum pc ON (pc.GZ_ABONAMENT_ID = ab.GZ_ABONAMENT_ID)
INNER JOIN GZ_IU iu ON (iu.GZ_PUNCTCONSUM_ID = pc.GZ_PUNCTCONSUM_ID)
LEFT OUTER JOIN C_BPartner_Location bplo ON (ab.C_BPartner_Location_ID = bplo.C_BPARTNER_LOCATION_ID)
LEFT OUTER JOIN C_Location lo ON (bplo.C_Location_ID = lo.C_Location_ID)
LEFT OUTER JOIN C_City cy ON (lo.C_City_ID = cy.C_City_ID)
GROUP BY cy.Name