SQL Stored Procedure Combine UNION rows into 1 row - sql

I would love to know how to put the results of this query into one row instead of 3 rows it gives back:
SELECT COUNT([fms].[dbo].[Booking].BOOKINGNUMBER) FROM [fms].[dbo].[Booking]
INNER JOIN [fms].[dbo].[Container] ON [fms].[dbo].[Booking].[BOOKINGNUMBER] = [fms].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fms].[dbo].[File] ON [fms].[dbo].[Container].FILENUMBER = [fms].[dbo].[File].FILENUMBER
WHERE [fms].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fms].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
UNION ALL
SELECT COUNT([fmsAir].[dbo].[Booking].BOOKINGNUMBER) FROM [fmsAir].[dbo].[Booking]
INNER JOIN [fmsAir].[dbo].[Container] ON [fmsAir].[dbo].[Booking].[BOOKINGNUMBER] = [fmsAir].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fmsAir].[dbo].[File] ON [fmsAir].[dbo].[Container].FILENUMBER = [fmsAir].[dbo].[File].FILENUMBER
WHERE [fmsAir].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fmsAir].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
UNION ALL
SELECT COUNT([fmsProjects].[dbo].[Booking].BOOKINGNUMBER) FROM [fmsProjects].[dbo].[Booking]
INNER JOIN [fmsProjects].[dbo].[Container] ON [fmsProjects].[dbo].[Booking].[BOOKINGNUMBER] = [fmsProjects].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fmsProjects].[dbo].[File] ON [fmsProjects].[dbo].[Container].FILENUMBER = [fmsProjects].[dbo].[File].FILENUMBER
WHERE [fmsProjects].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fmsProjects].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
Is there a way that I can combine the 3 result rows and count them into 1 row. I am using this inside a stored procedure.

If you want to SUM all the count of all 3 SELECT queries, You could you this:
SELECT SUM(cnt)
FROM(
SELECT COUNT([fms].[dbo].[Booking].BOOKINGNUMBER) cnt
FROM [fms].[dbo].[Booking]
INNER JOIN [fms].[dbo].[Container] ON [fms].[dbo].[Booking].[BOOKINGNUMBER] = [fms].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fms].[dbo].[File] ON [fms].[dbo].[Container].FILENUMBER = [fms].[dbo].[File].FILENUMBER
WHERE [fms].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fms].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
UNION ALL
SELECT COUNT([fmsAir].[dbo].[Booking].BOOKINGNUMBER)
FROM [fmsAir].[dbo].[Booking]
INNER JOIN [fmsAir].[dbo].[Container] ON [fmsAir].[dbo].[Booking].[BOOKINGNUMBER] = [fmsAir].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fmsAir].[dbo].[File] ON [fmsAir].[dbo].[Container].FILENUMBER = [fmsAir].[dbo].[File].FILENUMBER
WHERE [fmsAir].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fmsAir].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
UNION ALL
SELECT COUNT([fmsProjects].[dbo].[Booking].BOOKINGNUMBER)
FROM [fmsProjects].[dbo].[Booking]
INNER JOIN [fmsProjects].[dbo].[Container] ON [fmsProjects].[dbo].[Booking].[BOOKINGNUMBER] = [fmsProjects].[dbo].[Container].[BOOKINGNUMBER]
INNER JOIN [fmsProjects].[dbo].[File] ON [fmsProjects].[dbo].[Container].FILENUMBER = [fmsProjects].[dbo].[File].FILENUMBER
WHERE [fmsProjects].[dbo].[Booking].RELATIONCODE = 'SHIP02' AND [fmsProjects].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28'
) AS tmp;

Here is one way
SELECT (SELECT Count([fms].[dbo].[Booking].BOOKINGNUMBER)
FROM [fms].[dbo].[Booking]
.......
WHERE [fms].[dbo].[Booking].RELATIONCODE = 'SHIP02'
AND [fms].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28') as fms_count,
(SELECT Count([fmsAir].[dbo].[Booking].BOOKINGNUMBER)
FROM [fmsAir].[dbo].[Booking]
.......
WHERE [fmsAir].[dbo].[Booking].RELATIONCODE = 'SHIP02'
AND [fmsAir].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28') as fmsAir_count,
(SELECT Count([fmsProjects].[dbo].[Booking].BOOKINGNUMBER)
FROM [fmsProjects].[dbo].[Booking]
.....
WHERE [fmsProjects].[dbo].[Booking].RELATIONCODE = 'SHIP02'
AND [fmsProjects].[dbo].[File].ETA BETWEEN '2000-10-27' AND '2016-10-28') as fmsProjects_count

Who can read such a query? Use table aliases!
SELECT COUNT(b.BOOKINGNUMBER)
FROM [fms].[dbo].[Booking] b INNER JOIN
[fms].[dbo].[Container] c
ON b.[BOOKINGNUMBER] = c.[BOOKINGNUMBER] INNER JOIN
[fms].[dbo].[File] f
ON [c.FILENUMBER = f.FILENUMBER
WHERE b.RELATIONCODE = 'SHIP02' AND [f.ETA BETWEEN '2000-10-27' AND '2016-10-28';
As for getting these in one row, one method is just to use subqueries:
SELECT (SELECT COUNT(b.BOOKINGNUMBER)
FROM [fms].[dbo].[Booking] b INNER JOIN
[fms].[dbo].[Container] c
ON b.[BOOKINGNUMBER] = c.[BOOKINGNUMBER] INNER JOIN
[fms].[dbo].[File] f
ON [c.FILENUMBER = f.FILENUMBER
WHERE b.RELATIONCODE = 'SHIP02' AND [f.ETA BETWEEN '2000-10-27' AND '2016-10-28'
) as fms_count,
(SELECT COUNT(b.BOOKINGNUMBER)
FROM [fmsair].[dbo].[Booking] b INNER JOIN
[fmsair].[dbo].[Container] c
ON b.[BOOKINGNUMBER] = c.[BOOKINGNUMBER] INNER JOIN
[fmsair].[dbo].[File] f
ON [c.FILENUMBER = f.FILENUMBER
WHERE b.RELATIONCODE = 'SHIP02' AND [f.ETA BETWEEN '2000-10-27' AND '2016-10-28'
) as fmsair_count,
(SELECT COUNT(b.BOOKINGNUMBER)
FROM [fmsprojects].[dbo].[Booking] b INNER JOIN
[fmsprojects].[dbo].[Container] c
ON b.[BOOKINGNUMBER] = c.[BOOKINGNUMBER] INNER JOIN
[fmsprojects].[dbo].[File] f
ON [c.FILENUMBER = f.FILENUMBER
WHERE b.RELATIONCODE = 'SHIP02' AND [f.ETA BETWEEN '2000-10-27' AND '2016-10-28'
) as fmsprojects_count

Related

Sum from the different tables Sql server

I have couple of tables which stores amount and I want to group by and get sum - reason for the mutiple tables are nhibernate descriminators.
I am using Union all and works but query is very big.
I am using following query
SELECT CustomerAccountNumber,
vc.CustomerName,
SUM(PermAmount) AS PermAmount,
SUM(FreetextAmount) AS FreetextAmount,
(SUM(PermAmount) + SUM(FreetextAmount)) AS TotalAmountByCustomer
FROM
(
SELECT pp.CustomerAccountNumber,
pl.Amount AS PermAmount,
0 AS FreetextAmount
FROM dbo.PermanentPlacementTransactionLine pl
INNER JOIN dbo.TransactionLine tl ON pl.TransactionLineId = tl.Id
INNER JOIN dbo.PermanentPlacement pp ON pl.PermanentPlacementId = pp.Id
WHERE tl.CurrentStatus = 1
GROUP BY pp.CustomerAccountNumber,
pl.Amount,
tl.Id
UNION ALL
SELECT ft.CustomerAccountNumber,
0 AS PermAmount,
ft.Amount AS FreetextAmount
FROM dbo.FreeTextTransactionLine fttl
INNER JOIN dbo.TransactionLine tl ON fttl.TransactionLineId = tl.Id
INNER JOIN dbo.[FreeText] ft ON fttl.FreeTextId = ft.Id
WHERE tl.CurrentStatus = 1
GROUP BY ft.CustomerAccountNumber,
ft.Amount,
tl.Id
) WIPSummary
INNER JOIN dbo.vw_Customer vc ON WIPSummary.CustomerAccountNumber = vc.CustomerAccount
GROUP BY CustomerAccountNumber,
vc.CustomerName;
is there any elegant way of displaying amount in separate columns ?
I can use partition by if it was same table and want to display row by row.
Try these query, is easy to understand and probably faster than yours.
I assume that the values are unique in your view
WITH cte_a
AS (SELECT pp.customeraccountnumber
,Sum(pl.amount) AS PermAmount
,0 AS FreetextAmount
FROM dbo.permanentplacementtransactionline pl
INNER JOIN dbo.transactionline tl
ON pl.transactionlineid = tl.id
INNER JOIN dbo.permanentplacement pp
ON pl.permanentplacementid = pp.id
WHERE tl.currentstatus = 1
GROUP BY pp.customeraccountnumber),
cte_b
AS (SELECT ft.customeraccountnumber
,0 AS PermAmount
,Sum(ft.amount) AS FreetextAmount
FROM dbo.freetexttransactionline fttl
INNER JOIN dbo.transactionline tl
ON fttl.transactionlineid = tl.id
INNER JOIN dbo.[freetext] ft
ON fttl.freetextid = ft.id
WHERE tl.currentstatus = 1
GROUP BY ft.customeraccountnumber)
SELECT vc.customeraccountnumber
,vc.customername
,Isnull(A.permamount, 0) AS PermAmount
,Isnull(B.freetextamount, 0) AS FreetextAmount
,Isnull(A.permamount, 0)
+ Isnull(B.freetextamount, 0) AS TotalAmountByCustomer
FROM dbo.vw_customer vc
LEFT JOIN cte_a a
ON vc.customeraccount = A.customeraccountnumber
LEFT JOIN cte_b b
ON vc.customeraccount = A.customeraccountnumber
if no table structures and sample data, that is the best I can do to help you.

Max Query Over Partition

I want to select max values related to query, but all results are coming. Any idea ?
QUERY
SELECT MAXRecID,MAXSetID,MAXRID,PreReifiedValue,ComplianceState
FROM v_CI_CurrentComplianceStatus as A
INNER JOIN v_CIRules as B
ON B.CI_ID = A.CI_ID
INNER JOIN v_R_System as C
ON C.ResourceID = A.ItemKey
INNER JOIN
( SELECT PreReifiedValue,setting_CI_ID,
MAX(RecordID) AS MAXRecID,
MAX(SettingID) AS MAXSetID,
MAX(RuleID) AS MAXRID
FROM CI_CurrentRuleDetail
GROUP BY PreReifiedValue,Setting_CI_ID,instancedata
) AS D
ON D.Setting_CI_ID = A.CI_ID
GROUP by MAXRecID,MAXSetID,MAXRID,PreReifiedValue,rulename,ComplianceState
Results
MAXRecID MAXSetID MAXRID PreReifiedValue ComplianceState
72057594038117564 16780566 16780622 10 2
72057594038117565 16780570 16780620 0 2
Try this query
SELECT
MAX(tmp.MAXRecID), MAX(tmp.MAXSetID), MAX(tmp.MAXRID), MAX(tmp.PreReifiedValue), MAX(tmp.ComplianceState)
FROM (
SELECT MAXRecID,MAXSetID,MAXRID,PreReifiedValue,ComplianceState
FROM v_CI_CurrentComplianceStatus as A
INNER JOIN v_CIRules as B
ON B.CI_ID = A.CI_ID
INNER JOIN v_R_System as C
ON C.ResourceID = A.ItemKey
INNER JOIN
( SELECT PreReifiedValue,setting_CI_ID,
MAX(RecordID) AS MAXRecID,
MAX(SettingID) AS MAXSetID,
MAX(RuleID) AS MAXRID
FROM CI_CurrentRuleDetail
GROUP BY PreReifiedValue,Setting_CI_ID,instancedata
) AS D
ON D.Setting_CI_ID = A.CI_ID
) AS tmp
GROUP by tmp.MAXRecID, tmp.MAXSetID, tmp.MAXRID, tmp.PreReifiedValue, tmp.rulename, tmp.ComplianceState

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

Multiple SQL JOIN with multiple criteria

SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM ((tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON (A.SspStudent = B.StuID AND
B.StuAdmitTerm <> '201520A' AND
A.SspStatus = 'Schedul' AND
(A.SspTerm = '201520A' OR A.SspTerm = '201520B') AND
A.SspCreditHours <> 0))
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart)
LEFT OUTER JOIN D tblUser
ON B.StuAdvisorEmail = D.UseEmail;
I am trying to make this query work but everytime I try to adjust the parenthesis I get an error.
Could I get some help??
you are better off, with out those parenthesis, also you need to a sub query in the joins
Retained the parenthesis except in the OR AND condition , try this out.
SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND ( A.SspTerm = '201520A'
OR A.SspTerm = '201520B' )
AND A.SspCreditHours <> 0
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart
LEFT OUTER JOIN tblUser D
ON B.StuAdvisorEmail = D.UseEmail;
I indented your query. This is how I usually start to pick apart something with which I'm unfamilar.
SELECT
A.SspStudent
, B.StuLastName
, B.StuFirstName
, C.TerDescription
, A.SspCourseSubject
, A.SspCourseID
, A.SspCreditHours
, A.SspStatus
, B.StuEmailUNCW
, B.StuAdvisorEmail
, B.StuApplicationStatus
, D.UseName
FROM
(
(
tblStudentSchedulePerm A
INNER JOIN tblStudent B ON
(
A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND (A.SspTerm = '201520A' OR A.SspTerm = '201520B')
AND A.SspCreditHours <> 0
)
)
LEFT OUTER JOIN tblTerms C ON A.SspTerm = C.TerTermPart
)
LEFT OUTER JOIN D tblUser ON B.StuAdvisorEmail = D.UseEmail
;
D tblUser
should be :
tblUser D
Other than that, remove all useless parentheses:
SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND ( A.SspTerm = '201520A'
OR A.SspTerm = '201520B' )
AND A.SspCreditHours <> 0
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart
LEFT OUTER JOIN tblUser D
ON B.StuAdvisorEmail = D.UseEmail;

SQL select distinct entity - union all - order by another entity's column

I am using SQL to access an entity (Forslag), but would also like to sort using another entity's column (b.dato).
This is my initial SQL:
select distinct ff.*
from Forslag ff
inner join Forlag f on ff.forlag_id = f.forlag_id
inner join LoggBehandling b on ff.forlag_id = b.forlag_id
inner join Kontrollpanel p on f.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
union all
select distinct ft.*
from Forslag ft
inner join Tidsskrift t on ft.tidsskrift_id = t.tidsskrift_id
inner join LoggBehandling b on ft.tidsskrift_id = b.tidsskrift_id
inner join Kontrollpanel p on t.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
order by b.dato desc
Hibernate complains: ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.
I suspect I can't really add b.dato to select, as I assume this will have impact on the mapping:
select distinct ff.*, b.dato
from Forslag ff
inner join Forlag f on ff.forlag_id = f.forlag_id
inner join LoggBehandling b on ff.forlag_id = b.forlag_id
inner join Kontrollpanel p on f.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
union all
select distinct ft.*, b.dato
from Forslag ft
inner join Tidsskrift t on ft.tidsskrift_id = t.tidsskrift_id
inner join LoggBehandling b on ft.tidsskrift_id = b.tidsskrift_id
inner join Kontrollpanel p on t.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
order by b.dato desc
How should I solve this?
are you sure is HQL and not SQL???
The first: in HQL is not possible using UNION ALL but you must execute two distinct queries.
The second: in SQL when you use an order by when you have an UNION operation, you must apply ORDER BY to result table in this way:
The third: Why you use DISTINCT if you use UNION ALL?? Use UNION without ALL is the same thing of DISTINCT.
select *
from (
select ff.*, b.dato as dato
from Forslag ff
inner join Forlag f on ff.forlag_id = f.forlag_id
inner join LoggBehandling b on ff.forlag_id = b.forlag_id
inner join Kontrollpanel p on f.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
union all
select distinct ft.*, b.dato
from Forslag ft
inner join Tidsskrift t on ft.tidsskrift_id = t.tidsskrift_id
inner join LoggBehandling b on ft.tidsskrift_id = b.tidsskrift_id
inner join Kontrollpanel p on t.uhrPuMote_id = p.saksbehandlerUhrPuMote_id
where b.status_id = 7
) as resultTable
order by resultTable.dato desc