Problems with Sql query join - sql

I am struggling with a sql query. I want to include the sum from an other table.
SELECT DISTINCT
tblProject.CompanyID,
tblCompany.Name,
tblCompany.AvtalsKund,
tblProject.ProjectName,
tblProject.Estimate,
tblProject.ProjectStart,
tblProject.Deadline,
CONVERT(VARCHAR(8), tblProject.Deadline, 2) AS [YY.MM.DD] ,
tblProject.PreOffered,
tblProject.ProjectType,
tblProjectType.ProjType,
tblOrdered.FirstName + + tblOrdered.LastName as OrderedFullName,
tblProject.ProjectID,
tblProject.RegDate,
tblProject.ProjectNr,
tblProject.ProjectNr
FROM tblProject
INNER JOIN tblCompany ON tblProject.CompanyID = tblCompany.CompanyID
---> INNER JOIN (SELECT tblTimeRecord.ProjectID, SUM(CONVERT(float,replace([Hours],',','') ))
FROM tblTimeRecord group by tblTimeRecord.ProjectID) as b
ON b.ProjectID = tblProject.ProjectID
INNER JOIN tblTimeRecord ON tblTimeRecord.ProjectID = tblProject.ProjectID
INNER JOIN tblProjectType ON tblProject.ProjectType = tblProjectType.ProjTypeID
LEFT OUTER JOIN tblOrdered ON tblProject.OrderedBy = tblOrdered.OrderedID
LEFT OUTER JOIN tblRel_WorkerProject ON tblProject.ProjectID = tblRel_WorkerProject.ProjectID
LEFT OUTER JOIN tblPerson ON tblPerson.PersonID = tblRel_WorkerProject.WorkerID
LEFT OUTER JOIN tblRel_StatusWorkerProject ON tblProject.ProjectID = tblRel_StatusWorkerProject.ProjectID
I want to include this sum-block from table tblTimeRecord.
I get a sum of timerapports with this code
SELECT tblTimeRecord.ProjectID,
SUM(CONVERT(float,replace([Hours],',','') ))
FROM tblTimeRecord where ProjectID=1312 group by tblTimeRecord.ProjectID
Guess i do it in join?
Got it working with this.
SELECT DISTINCT
tblProject.ProjectID,
Summa,
tblProject.CompanyID,
tblCompany.Name,
tblCompany.AvtalsKund,
tblProject.ProjectName,
tblProject.Estimate,
tblProject.ProjectStart,
tblProject.Deadline,
CONVERT(VARCHAR(8), tblProject.Deadline, 2) AS [YY.MM.DD] ,
tblProject.PreOffered,
tblProject.ProjectType,
tblProjectType.ProjType,
tblOrdered.FirstName + + tblOrdered.LastName as OrderedFullName,
tblProject.ProjectID,
tblProject.RegDate,
tblProject.ProjectNr,
tblProject.ProjectNr
FROM tblProject
INNER JOIN tblCompany ON tblProject.CompanyID = tblCompany.CompanyID
INNER JOIN (SELECT tblTimeRecord.ProjectID, SUM(CONVERT(float,replace([Hours],',','') )) as Summa FROM tblTimeRecord group by tblTimeRecord.ProjectID) as b
ON b.ProjectID = tblProject.ProjectID
INNER JOIN tblTimeRecord ON tblTimeRecord.ProjectID = tblProject.ProjectID
INNER JOIN tblProjectType ON tblProject.ProjectType = tblProjectType.ProjTypeID
LEFT OUTER JOIN tblOrdered ON tblProject.OrderedBy = tblOrdered.OrderedID
LEFT OUTER JOIN tblRel_WorkerProject ON tblProject.ProjectID = tblRel_WorkerProject.ProjectID
LEFT OUTER JOIN tblPerson ON tblPerson.PersonID = tblRel_WorkerProject.WorkerID
LEFT OUTER JOIN tblRel_StatusWorkerProject ON tblProject.ProjectID = tblRel_StatusWorkerProject.ProjectID

There are two ways to do this.
You can use a WITH clause to create the aggregate table then join this to the main query.
Or do it this way:
SELECT m.BLAH
,m.FOO
,x.AMOUNT
FROM MAINTABLE m
LEFT JOIN
(
SELECT FOO
,SUM(AMOUNT) as AMOUNT
FROM OTHERTABLE
GROUP BY FOO
) x
ON m.FOO = x.FOO
I prefer the second way.

Related

Optimizing Multiple SQL Queries

I have 2 queries that I want to optimize but I don't know how. The execution time is not acceptable for me.
I'm working with jira database and did query to show different tasks with some attributes.
The code is:
SET NOCOUNT ON
DROP TABLE IF EXISTS #TT
DROP TABLE IF EXISTS #TT1
DROP TABLE IF EXISTS #TT2
SELECT DISTINCT concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ'
,concat('https://sd.finam.ru/browse/', pr.[pkey], '-', ji.[issuenum]) AS 'Ссылка'
,p.[pname] AS 'П'
,users.[display_name] AS 'Исполнитель'
,CAST(ji.[CREATED] AS smalldatetime) AS 'Создан'
,CAST(ji.[RESOLUTIONDATE] AS smalldatetime) AS 'Дата резолюции'
,ji.[issuenum]
INTO #TT
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [priority] AS p ON (p.[ID] = ji.[PRIORITY])
LEFT OUTER JOIN [project] AS pr ON (pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [cwd_user] as users ON (users.[user_name] = ji.[ASSIGNEE])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND itype.pname = 'Incident'
SELECT DISTINCT concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ'
,system_t.[NAME] AS 'Контур ИС'
,system_t_t.[NAME] AS 'Критичность системы'
INTO #TT1
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [project] AS pr ON (pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [customfieldvalue] AS customfv ON (customfv.[ISSUE] = ji.[ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ] AS system_t ON (system_t.[ID] = substring(customfv.[STRINGVALUE], PatIndex('%[0-9]%', customfv.[STRINGVALUE]), len(customfv.[STRINGVALUE])))
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ_ATTR] AS system_attr ON (system_t.[ID] = system_attr.[OBJECT_ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ_ATTR_VAL] AS system_attr_val ON (system_attr.[ID] = system_attr_val.[OBJECT_ATTRIBUTE_ID])
LEFT OUTER JOIN [AO_8542F1_IFJ_OBJ] AS system_t_t ON (system_attr_val.[REFERENCED_OBJECT_ID] = system_t_t.[ID])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND (customfv.[CUSTOMFIELD] = 21003 OR customfv.[CUSTOMFIELD] = 21005)
AND (system_t.[OBJECT_TYPE_ID] = 136 OR system_t.[OBJECT_TYPE_ID] = 303 OR system_t.[OBJECT_TYPE_ID] = 143)
AND system_attr.[OBJECT_TYPE_ATTRIBUTE_ID] = 461
AND itype.pname = 'Incident'
SELECT ji.[issuenum]
,pr_pr.[pname] AS '(project) Project'
INTO #TT2
FROM
[jiraissue] AS ji
LEFT OUTER JOIN [customfieldvalue] AS customfv ON (customfv.[ISSUE] = ji.[ID])
LEFT OUTER JOIN [project] AS pr_pr ON (pr_pr.[ID] = CAST(customfv.[NUMBERVALUE] AS BIGINT))
LEFT OUTER JOIN [changegroup] AS cg ON (cg.[issueid] = ji.[id])
LEFT OUTER JOIN [changeitem] AS ci ON (ci.[groupid] = cg.[id]) AND ci.FIELDTYPE='jira' AND ci.FIELD='status'
LEFT OUTER JOIN [app_user] AS au ON (au.[user_key] = cg.[AUTHOR])
LEFT OUTER JOIN [issuetype] AS itype ON (itype.[ID] = ji.[issuetype])
WHERE cg.[CREATED] >= CONVERT(datetime, '2021-12-01') AND cg.[CREATED] <= CONVERT(datetime, '2022-01-01') and CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done'
AND pr_pr.[pname] is not NULL
SELECT CTE.[Ключ], CTE.[Ссылка], CTE.[П], CTE.[Исполнитель], CTE.[Создан], CTE.[Дата резолюции], CTE2.[(project) Project], CTE1.[Контур ИС], CTE1.[Критичность системы], CTE.[issuenum]
FROM #TT CTE
LEFT OUTER JOIN #TT1 CTE1 ON (CTE1.[Ключ] = CTE.[Ключ])
LEFT OUTER JOIN #TT2 CTE2 ON (CTE2.[issuenum] = CTE.[issuenum])
DROP TABLE IF EXISTS #TT
DROP TABLE IF EXISTS #TT1
DROP TABLE IF EXISTS #TT2
There will be some information for the month before last.
summary of query
The next query is:
WITH CTE AS (
SELECT concat(p.pkey,'-',i.issuenum) AS 'Ключ',
cf.cfname,
cv.textvalue,
ROW_NUMBER() OVER (PARTITION BY i.issuenum ORDER BY i.issuenum) AS RowNumber_SLA
FROM customfield cf,
customfieldvalue cv,
jiraissue i,
project p
WHERE i.project = p.id
AND cv.issue = i.id
AND cv.customfield = cf.id
AND cf.customfieldtypekey = 'com.atlassian.servicedesk:sd-sla-field'
and i.issuenum IN ()
and CHARINDEX('"succeeded":false', TEXTVALUE) >0
)
SELECT CTE.Ключ
FROM CTE
WHERE RowNumber_SLA = 1
The goal is to get tasks where SLA has been failed.
So in and i.issuenum IN () my Python script is putting issue numbers that I got through previous query.
The average execution time is 3 minutes.
So, I want optimize this too, maybe join first query.
Sorry for my English. I'm not an English-speaking person.
P. S. Changing CONVERT(NVARCHAR(MAX), ci.[NEWSTRING]) = N'Done' to ci.[NEWSTRING] = 'Done' causing the error The data types ntext and varchar are incompatible in the equal to operator. Workaround - ci.[NEWSTRING] LIKE 'Done' fixing this.
The first query must be rewrite as :
SELECT DISTINCT
concat(pr.[pkey], '-', ji.[issuenum]) AS 'Ключ',
concat('https://sd.finam.ru/browse/', pr.[pkey], '-', ji.[issuenum]) AS 'Ссылка',
p.[pname] AS 'П',
users.[display_name] AS 'Исполнитель',
CAST(ji.[CREATED] AS SMALLDATETIME) AS 'Создан',
CAST(ji.[RESOLUTIONDATE] AS SMALLDATETIME) AS 'Дата резолюции',
ji.[issuenum]
INTO #TT
FROM [jiraissue] AS ji
INNER JOIN [changegroup] AS cg ON(cg.[issueid] = ji.[id])
INNER JOIN [changeitem] AS ci ON(ci.[groupid] = cg.[id])
AND ci.FIELDTYPE = 'jira'
AND ci.FIELD = 'status'
LEFT OUTER JOIN [app_user] AS au ON(au.[user_key] = cg.[AUTHOR])
INNER JOIN [issuetype] AS itype ON(itype.[ID] = ji.[issuetype])
LEFT OUTER JOIN [priority] AS p ON(p.[ID] = ji.[PRIORITY])
LEFT OUTER JOIN [project] AS pr ON(pr.[ID] = ji.[PROJECT])
LEFT OUTER JOIN [cwd_user] AS users ON(users.[user_name] = ji.[ASSIGNEE])
WHERE cg.[CREATED] >= CONVERT(DATETIME, '2021-12-01')
AND cg.[CREATED] <= CONVERT(DATETIME, '2022-01-01')
AND ci.[NEWSTRING] = 'Done'
AND itype.pname = 'Incident';
False outer joins are converted in INNER and I have aslo eliminate the ugly CONVERT to NVARCHAR(max)
Same troubles appears in the second query...

Best Join Strategy/Indexes for SQL Server

What is the best join strategy/indexes for this query:
SELECT
kwk.*, an.AuftragDatum, an.AbgabeDatum, an.BezahltDatum, an.AuftragStatus
FROM
KundenWerbenKunden kwk
INNER JOIN
Auftrag an ON an.AuftragNummer = kwk.AuftragNummer
WHERE
kwk.Deleted = 0
Table KundenWerbenKunden has 103950 rows with 103646 Deleted = 0 ones.
Table Auftrag has 3826552 rows.
In my real query I make some more joins:
INNER JOIN
Filiale fn WITH (NOLOCK) ON an.FilialeID = fn.FilialeID
INNER JOIN
Kunde kn ON an.KundeID = kn.KundeID
OUTER APPLY
(SELECT DISTINCT KSKNr
FROM KdZuordnung
WHERE KundeID = kn.KundeID) zn
LEFT JOIN
Anrede ann WITH (NOLOCK) ON kn.Anrede = ann.Anrede
INNER JOIN
AuftragArt aa WITH (NOLOCK) ON an.AuftragArtID = aa.AuftragArtID
INNER JOIN
AuftragGrund ag WITH (NOLOCK) ON an.AuftragGrundID = ag.AuftragGrundID
INNER JOIN
AuftragType at WITH (NOLOCK) ON an.AuftragTypeID = at.AuftragTypeID
For this query:
SELECT *
FROM KundenWerbenKunden kwk INNER JOIN
Auftrag an
ON an.AuftragNummer = kwk.AuftragNummer
WHERE kwk.Geloescht = 0;
And not knowing anything about the distribution of Geloescht, I would first try indexes on KundenWerbenKunden(Geloescht, AuftragNummer) and Auftrag(AuftragNummer).

Nested SQL Statements2

What tables are present in this code?
SELECT
ProjectUID,
ProjectName,
FROM
(SELECT
MSP_TimesheetPeriod.PeriodName AS PeriodName,
MSP_TimesheetPeriod.PeriodUID AS PeriodUID,
FROM
(SELECT
MSP_TimesheetLine.TimesheetLineUID,
MSP_TimesheetActual.TimeByDay AS TimeByDay, --
SUM(MSP_TimesheetActual.PlannedWork) AS PlannedWork,
FROM
dbo.MSP_TimesheetLine
LEFT OUTER JOIN
dbo.MSP_TimesheetActual ON MSP_TimesheetLine.TimesheetLineUID = MSP_TimesheetActual.TimesheetLineUID) AS TimesheetLineData
INNER JOIN
dbo.MSP_TimesheetLine ON MSP_TimesheetLine.TimesheetLineUID = TimesheetLineData.TimesheetLineUID) AS MSP_TimesheetLine_UserView
INNER JOIN
MSP_TimesheetLine_OlapView AS ov ON MSP_TimesheetLine_UserView.TimesheetLineUID = ov.TimesheetLineUID

connot perform an aggregate function ... with GROUP BY

Hello i'm trying to write a query which consists to calculate the sum of 2 values, the second sum is result of multiplication between the first value and another. could someone help to solve this please ?? ( excuse me for my english, im frensh developer ) :
SELECT ISNULL(CONVERT(VARCHAR,CONVERT(date,MARE_DAT_CRE,103)),'Total') AS Dat
, SUM (MARE_CAUTIONNEMENT) AS HT
, SUM ( MARE_CAUTIONNEMENT * ( SELECT DISTINCT LCF_TAUXTVA
FROM F_LIGNECOMFOU
INNER JOIN F_AFFAIRES ON LCF_CODE_AFF = AF_CODE_AFFAIRE
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_COMMANDEFOU ON CF_NUMERO = LCF_CF_NUMERO
INNER JOIN F_P_FOURNISSEUR ON CF_IDENT_FO = FOU_IDENT
WHERE AF_CODE_AFFAIRE = '15065-00' AND LT_IDENT = 500002200 AND FOU_IDENT = 500000838 ) ) FROM F_AVENANT_RETENUE INNER JOIN F_MARCHE_AVENANT ON MAAV_IDENT = MARE_MAAV_IDENT INNER JOIN F_MARCHE_TRAVAUX ON MATR_IDENT = MAAV_MATR_IDENT INNER JOIN F_AFFAIRES ON AF_CODE_AFFAIRE = MATR_AF_IDENT INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE INNER JOIN F_AVENANT_COTATION ON AVCO_IDENT = MARE_AVCO_IDENT WHERE AF_CODE_AFFAIRE = '15065-00' AND LT_IDENT = 500002200 AND MATR_FOU_IDENT = 500000838 AND MARE_CAUTIONNEMENT IS NOT NULL
GROUP BY MARE_DAT_CRE WITH ROLLUP
You could try sticking that sub select in your joins. Now you haven't used table alias so I'm not sure which tables contain the fields AF_CODE_AFFAIRE, LT_IDENT and MATR_FOU_IDENT so you'll have to add table aliases;
SELECT ISNULL(CONVERT(VARCHAR, CONVERT(DATE, MARE_DAT_CRE, 103)), 'Total') AS Dat
,SUM(MARE_CAUTIONNEMENT) AS HT
,SUM(MARE_CAUTIONNEMENT) * SUM(new.LCF_TAUXTVA)
FROM F_AVENANT_RETENUE
INNER JOIN F_MARCHE_AVENANT ON MAAV_IDENT = MARE_MAAV_IDENT
INNER JOIN F_MARCHE_TRAVAUX ON MATR_IDENT = MAAV_MATR_IDENT
INNER JOIN F_AFFAIRES ON AF_CODE_AFFAIRE = MATR_AF_IDENT
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_AVENANT_COTATION ON AVCO_IDENT = MARE_AVCO_IDENT
LEFT JOIN (
SELECT DISTINCT LCF_TAUXTVA
FROM F_LIGNECOMFOU
INNER JOIN F_AFFAIRES ON LCF_CODE_AFF = AF_CODE_AFFAIRE
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_COMMANDEFOU ON CF_NUMERO = LCF_CF_NUMERO
INNER JOIN F_P_FOURNISSEUR ON CF_IDENT_FO = FOU_IDENT
) new ON AF_CODE_AFFAIRE = new.AF_CODE_AFFAIRE
AND LT_IDENT = new.LT_IDENT
AND MATR_FOU_IDENT = new.MATR_FOU_IDENT
WHERE AF_CODE_AFFAIRE = '15065-00'
AND LT_IDENT = 500002200
AND MATR_FOU_IDENT = 500000838
AND MARE_CAUTIONNEMENT IS NOT NULL
GROUP BY ISNULL(CONVERT(VARCHAR, CONVERT(DATE, MARE_DAT_CRE, 103)), 'Total')
WITH ROLLUP

Inner join more than 2 tables in a single database

i want to innerjoin more than 3 tables in one select query in one database all of them are having rm_id as a common column but i want to display the rows of all tables in one sql query is it possible if it is then i would hearly request u to provide some code
select * from
bk_det inner join
bk_rep inner join
bk_sec inner join
mut_det inner join
rm_det inner join
soil_det
on
bk_det.rm_id = bk_rep.rm_id = bk_sec.rm_id = mut_det.rm_id = rm_det.rm_id = soil_det.rm_id
You need an on clause for each inner join. e.g.
select * from a
inner join b on a.id = b.id
inner join c on b.id = c.id
You are missing the ON clause for each join:
select *
from bk_det
inner join bk_rep
on bk_det.rm_id = bk_rep.rm_id
inner join bk_sec
on bk_rep.rm_id = bk_sec.rm_id
inner join mut_det
on bk_sec.rm_id = mut_det.rm_id
inner join rm_det
on mut_det.rm_id = rm_det.rm_id
inner join soil_det
on rm_det.rm_id = soil_det.rm_id
Note: you will have to check the join condition column names since I do not know your table structure
If you need help with learning join syntax, here is a great visual explanation of joins.
Since you are using an INNER JOIN this will return records if the rm_id exists in each table.
You might need to use a LEFT JOIN:
select *
from bk_det
left join bk_rep
on bk_det.rm_id = bk_rep.rm_id
left join bk_sec
on bk_rep.rm_id = bk_sec.rm_id
left join mut_det
on bk_sec.rm_id = mut_det.rm_id
left join rm_det
on mut_det.rm_id = rm_det.rm_id
left join soil_det
on rm_det.rm_id = soil_det.rm_id