SQL Server 2012 - Adding a summary row - sql-server-2012

I have this code
SELECT
B.TABLENAME AS [TABLE NAME],
B.SIZE AS [SIZE PRE-CLEANUP GIG(S)],
A.SIZE AS [SIZE POST-CLEANUP GIG(S)],
B.SIZE - A.SIZE AS [SIZE CHANGE GIG(S)],
CASE
WHEN B.SIZE = 0 OR A.SIZE = 0
THEN '0.0%'
ELSE FORMAT((B.SIZE-A.SIZE)/B.SIZE, 'P1')
END AS [PERCENTAGE OF CHANGE]
FROM
ZERO_BALANCE.DBO.TMP_TABLE_STATS_BEG AS B
JOIN
ZERO_BALANCE.DBO.TMP_TABLE_STATS_END AS A ON A.TABLENAME = B.TABLENAME
which display a table that looks like the attached image. How would I make a summary row for this?

Related

SQL Addition of two Temp Tables

I have two temp tables that are counting a number of IDs. I want to combine those tables to give the count for each and then add those together. This is what I have so far.
if object_id('tempdb..#order') is not null drop table #order
select count (a.patientSID) as 'Order Count'
into #order
from CPRSOrder.CPRSOrder a
join sstaff.SStaff b on b.staffSID = a.EnteredbyStaffSID
join spatient.spatient c on c.patientSID = a.patientSID
where b.staffName = xxxxxxxx
and a.enteredDateTime >= '20180801' and a.enteredDateTime <= '20180828'
if object_id('tempdb..#note') is not null drop table #note
select count (a.patientSID) as 'Note Count'
into #note
from tiu.tiudocument a
join sstaff.SStaff b on b.staffSID = a.EnteredbyStaffSID
--join spatient.spatient c on c.patientSID = a.patientSID
where b.staffName = xxxxxxxx
and a.episodeBeginDateTime >= '20180801' and a.episodeBeginDateTime <= '20180828'
select (select [Note Count] from #note) as 'Note Count',
(select [Order Count] from #order) as 'Order Count',
sum((select [Order Count] from #order) + (select [Note Count] from #note)) as Total
Remove the sum(), unless you want to aggregate. Also, since the tables contain only one row each, this could be simplified a little by using a cross join.
SELECT n.[Note Count],
o.[Order Count],
n.[Note Count] + o.[Order Count] [Total]
FROM #note n
CROSS JOIN #order o;
While there's nothing syntactically wrong with selecting a single column from a temp table, what is clear is you are using an entire temp table to save a single value, an aggregated sum. An integer variable can also hold a count. For example:
DECLARE #order int =
(
select count (a.patientSID)
from CPRSOrder.CPRSOrder a
join sstaff.SStaff b on b.staffSID = a.EnteredbyStaffSID
join spatient.spatient c on c.patientSID = a.patientSID
where b.staffName = xxxxxxxx
and a.enteredDateTime >= '20180801' and a.enteredDateTime <= '20180828'
)
DECLARE #note int = (
select count (a.patientSID)
from tiu.tiudocument a
join sstaff.SStaff b on b.staffSID = a.EnteredbyStaffSID
--join spatient.spatient c on c.patientSID = a.patientSID
where b.staffName = xxxxxxxx
and a.episodeBeginDateTime >= '20180801' and a.episodeBeginDateTime <= '20180828'
)
SELECT #note AS [note count]
,#order AS [order count]
,#order + #note AS [total]

SQL-SERVER : Sub query for every row of the outer Select

Well i am creating a stored procedure in which i would like the sub-queries to be executed for each row of the outer select.
Every account has some payments and receipts that are stored in the same column.
For each account i would like to produce the sum of this column
The sub-queries create two columns PAYMENTS_SUM and RECEIPTS_SUM.The problem is that even if the summaries are produced they are executed only once.After some search i found out that this is the expected behavior.
But how can i produce these sums for each ACC.ACCOUNTID
BEGIN
SET NOCOUNT ON
SELECT DiSTINCT
ACC.ACCOUNT,
BM.CCY,
ACC.SEG,
(SELECT SUM(BM.ADJUSTMENT) AS PAYMENTS_SUM FROM [dbo].[Accounts] ACC
LEFT join [dbo].[BalanceMovements] BM ON BM.ACCOUNTID = ACC.ACCOUNTID collate database_default
WHERE
ACC.Account = ACC.ACCOUNT And
Month(BM.COB) = MONTH(GETDATE())
AND
YEAR(BM.COB) = YEAR(GETDATE())
AND
BM.ADJUSTMENT > 0
)
AS PAYMENTS_SUM,
(SELECT SUM(BM.ADJUSTMENT) AS PAYMENTS_SUM FROM [dbo].[Accounts] ACC
LEFT join [dbo].[BalanceMovements] BM ON BM.ACCOUNTID = ACC.ACCOUNTID collate database_default
WHERE
ACC.Account = ACC.ACCOUNT AND
Month(BM.COB) = MONTH(GETDATE())
AND
YEAR(BM.COB) = YEAR(GETDATE())
AND
BM.ADJUSTMENT < 0
)
AS RECEIPTS_SUM,
ACC.SystemAccount,
ACC.ENTITY,
ACC.BusinessGroup
FROM [dbo].[Accounts] ACC
LEFT join [dbo].[BalanceMovements] BM ON BM.ACCOUNTID = ACC.ACCOUNTID collate database_default
WHERE
Month(BM.COB) = MONTH(GETDATE())
AND
YEAR(BM.COB) = YEAR(GETDATE())
END
As you can see the result has the same value for each account.
This answer is a speculation, but hopefully gets closer to what you want. The idea is that you just want to conditionally aggregate the adjustment amount depending some various conditions. The other non aggregate columns are pretty much along for the ride, so we can just add them to GROUP BY clause.
SELECT
ACC.ACCOUNT,
BM.CCY,
ACC.SEG,
ACC.SystemAccount,
ACC.ENTITY,
ACC.BusinessGroup,
SUM(CASE WHEN BM.ADJUSTMENT > 0 THEN BM.ADJUSTMENT ELSE 0 END) AS PAYMENTS_SUM,
SUM(CASE WHEN BM.ADJUSTMENT <= 0 THEN BM.ADJUSTMENT ELSE 0 END) AS RECEIPTS_SUM
FROM [dbo].[Accounts] ACC
LEFT join [dbo].[BalanceMovements] BM
ON BM.ACCOUNTID = ACC.ACCOUNTID collate database_default
WHERE
MONTH(BM.COB) = MONTH(GETDATE()) AND YEAR(BM.COB) = YEAR(GETDATE())
GROUP BY
ACC.ACCOUNT,
BM.CCY,
ACC.SEG,
ACC.SystemAccount,
ACC.ENTITY,
ACC.BusinessGroup;

Move one reord to top

I am using SQL Server. I have the below table (marked yellow). I am in a situation to generate the output (marked green) like this.
Conditions to use in the query:
When cal_wk is 1 then target_hrs value should take from cal_wk 2
When target_hrs is empty then target_hrs should be maximum of the result
I am trying the case statement like
select
r.hour_val,
case
when us.calwk = 1
then 2
else us.calwk
end as cal_wk,
hrswk as target_hrs, u.uid
from
table1 us
inner join
users u on u.username = us.username
inner join
table2 r on u.uid = r.uid
where
us.yr = 2016
and u.uid = 2643
and r.cur_month = 7
and r.week_val = us.calwk
order by
us.calwk
This is just changing cal_wk value not target_hrs.
Could any one write a query to generate the expected_target_hrs?
Thanks in advance for your support
Try
Select
Case when calwk = 1 then wk2_max
When calwk = 0 then max
Else target_hrs end as expected_target_hours
From [table name]
Inner join
(Select max(case when calwk = 2 then target_hrs else 0 end) as wk2_max,
Max(target_hrs) as max
From [table name])
On 1 = 1
Following your update to the question, you will need to replace [table name] with that join.

"Having" in SQL

I have a SQL like this below
SELECT A.UNIT, A.PO_NO, A.LINE, A.QUNATITY,
SUM(B.RECEIVED_QUNATITY) AS "RECEIVED QUANTITY"
FROM PO_TBL A, RECEIVER_TBL B
WHERE A.UNIT = B.UNIT AND A.PO_NO = B.PO_NO AND A.LINE = B.LINE
GROUP BY A.UNIT, A.PO_NO, A.LINE, A.QUNATITY
HAVING ((A.QUNATITY - SUM(B.RECEIVED_QUNATITY)) > 0);
The above SQL return more rows if the Having function is not used and returns null rows, when we using Having function. Even though, Quantity has value as "10" and RECEIVED_QUNATITY has value as "0", that rows are not shown in the output.
Kindly help me on this scenario......
Try this one.
I just place isnull function to check null values.
SELECT A.UNIT, A.PO_NO, A.LINE, A.QUNATITY,
SUM(B.RECEIVED_QUNATITY) AS "RECEIVED QUANTITY"
FROM PO_TBL A, RECEIVER_TBL B
WHERE A.UNIT = B.UNIT AND A.PO_NO = B.PO_NO AND A.LINE = B.LINE
GROUP BY A.UNIT, A.PO_NO, A.LINE, A.QUNATITY
HAVING ((A.QUNATITY - isnull(SUM(B.RECEIVED_QUNATITY),0)) > 0);
Assuming A.Quantity doesn't have null values or else implement isnull over it also.

TOP Returning null

I have the following view below. The second nested select is always returning null when I use the TOP(1) clause, but when I remove this clause it returns the data as expected, just more rows than is needed. Does anyone see anything that would explain this?
SELECT TOP (100) PERCENT
a.ITEMID AS Model
,id.CONFIGID
,id.INVENTSITEID AS SiteId
,id.INVENTSERIALID AS Serial
,it.ITEMNAME AS Description
,CASE WHEN it.DIMGROUPID LIKE '%LR-Y' THEN 'Y'
ELSE 'N'
END AS SerialNumberReqd
,ISNULL(it.PRIMARYVENDORID, N'') AS Vendor
,ISNULL(vt.NAME, N'') AS VendorName
,id.INVENTLOCATIONID AS Warehouse
,id.WMSLOCATIONID AS Bin
,ISNULL(CONVERT(varchar(12), CASE WHEN C.DatePhysical < '1901-01-01'
THEN NULL
ELSE C.DatePhysical
END, 101), N' ') AS DeliveryDate
,CASE WHEN (a.RESERVPHYSICAL > 0
OR C.StatusIssue = 1)
AND c.TransType = 0 THEN C.PONumber
ELSE ''
END AS SoNumber
,'' AS SoDetail
,ISNULL(C.PONumber, N'') AS RefNumber
,ISNULL(CONVERT(varchar(12), CASE WHEN ins.ProdDate < '1901-01-01'
THEN NULL
ELSE ins.PRODDATE
END, 101), N' ') AS DateReceived
,it.STKSTORISGROUPID AS ProdGroup
,ISNULL(CONVERT(varchar(12), CASE WHEN ins.ProdDate < '1901-01-01'
THEN NULL
ELSE ins.PRODDATE
END, 101), N' ') AS ProductionDate
,it.ITEMGROUPID
,it.STKSTORISGROUPID AS MerchandisingGroup
,CASE WHEN a.postedValue = 0
THEN (CASE WHEN D.CostAmtPosted = 0 THEN D.CostAmtPhysical
ELSE D.CostAmtPosted
END)
ELSE a.POSTEDVALUE
END AS Cost
,CASE WHEN a.PHYSICALINVENT = 0 THEN a.Picked
ELSE a.PhysicalInvent
END AS PhysicalOnHand
,ins.STKRUGSQFT AS RugSqFt
,ins.STKRUGVENDSERIAL AS RugVendSerial
,ins.STKRUGVENDDESIGN AS RugVendDesign
,ins.STKRUGEXACTSIZE AS RugExactSize
,ins.STKRUGCOUNTRYOFORIGIN AS RugCountryOfOrigin
,ins.STKRUGQUALITYID AS RugQualityId
,ins.STKRUGCOLORID AS RugColorId
,ins.STKRUGDESIGNID AS RugDesignId
,ins.STKRUGSHAPEID AS RugShapeId
,CASE WHEN (a.AVAILPHYSICAL > 0) THEN 'Available'
WHEN (id.WMSLOCATIONID = 'NIL') THEN 'Nil'
WHEN (a.RESERVPHYSICAL > 0)
AND (c.TransType = 0) THEN 'Committed'
WHEN (a.RESERVPHYSICAL > 0) THEN 'Reserved'
WHEN (id.WMSLOCATIONID LIKE '%-Q') THEN 'Damaged'
WHEN (a.Picked > 0) THEN 'Picked'
ELSE 'UNKNOWN'
END AS Status
,'' AS ReasonCode
,'' AS BaseModel
,ISNULL(CAST(ins.STKSTORISCONFIGINFO AS nvarchar(1000)), N'') AS StorisConfigInfo
,ISNULL(C.ConfigSummary, N'') AS ConfigSummary
FROM
dbo.INVENTSUM AS a WITH (NOLOCK)
INNER JOIN dbo.INVENTDIM AS id WITH (NOLOCK)
ON id.DATAAREAID = a.DATAAREAID
AND id.INVENTDIMID = a.INVENTDIMID
LEFT OUTER JOIN dbo.INVENTTABLE AS it WITH (NOLOCK)
ON it.DATAAREAID = a.DATAAREAID
AND it.ITEMID = a.ITEMID
LEFT OUTER JOIN dbo.VENDTABLE AS vt WITH (NOLOCK)
ON vt.DATAAREAID = it.DATAAREAID
AND vt.ACCOUNTNUM = it.PRIMARYVENDORID
LEFT OUTER JOIN dbo.INVENTSERIAL AS ins WITH (NOLOCK)
ON ins.DATAAREAID = id.DATAAREAID
AND ins.INVENTSERIALID = id.INVENTSERIALID
LEFT OUTER JOIN (SELECT TOP (1)
itt.ITEMID
,invt.INVENTSERIALID
,itt.DATEPHYSICAL AS DatePhysical
,itt.TRANSREFID AS PONumber
,itt.TRANSTYPE AS TransType
,itt.STATUSISSUE AS StatusIssue
,dbo.stkRowsToColumn(itt.INVENTTRANSID, 'STI') AS ConfigSummary
,itt.RECID
FROM
dbo.INVENTTRANS AS itt WITH (NOLOCK)
INNER JOIN dbo.INVENTDIM AS invt WITH (NOLOCK)
ON invt.DATAAREAID = itt.DATAAREAID
AND invt.INVENTDIMID = itt.INVENTDIMID
WHERE
(itt.DATAAREAID = 'STI')
AND (itt.TRANSTYPE IN (0, 2, 3, 8))
AND (invt.INVENTSERIALID <> '')
ORDER BY
itt.RECID DESC) AS C
ON C.ITEMID = a.ITEMID
AND C.INVENTSERIALID = id.INVENTSERIALID
LEFT OUTER JOIN (SELECT TOP (1)
itt2.ITEMID
,invt2.INVENTSERIALID
,itt2.COSTAMOUNTPOSTED AS CostAmtPosted
,itt2.COSTAMOUNTPHYSICAL + itt2.COSTAMOUNTADJUSTMENT AS CostAmtPhysical
,itt2.RECID
FROM
dbo.INVENTTRANS AS itt2 WITH (NOLOCK)
INNER JOIN dbo.INVENTDIM AS invt2 WITH (NOLOCK)
ON invt2.DATAAREAID = itt2.DATAAREAID
AND invt2.INVENTDIMID = itt2.INVENTDIMID
WHERE
(itt2.DATAAREAID = 'STI')
AND (itt2.TRANSTYPE IN (0, 2, 3, 4, 6, 8))
AND (invt2.INVENTSERIALID <> '')
ORDER BY
itt2.RECID DESC) AS D
ON D.ITEMID = a.ITEMID
AND D.INVENTSERIALID = id.INVENTSERIALID
WHERE
(a.DATAAREAID = 'STI')
AND (a.CLOSED = 0)
AND (a.PHYSICALINVENT > 0)
AND (it.ITEMGROUPID LIKE 'FG-%'
OR it.ITEMGROUPID = 'MULTISHIP')
ORDER BY
SiteId
,Warehouse
Presumably, the top value in the subquery doesn't meet the subsequent join conditions. That is, this condition is not met:
D.ITEMID = a.ITEMID AND D.INVENTSERIALID = id.INVENTSERIALID
You are using a left outer join, so NULL values are filled in.
EDIT:
To re-iterate. When you run it with top 1, there are no values (for at least some combinations of the two variables). So, NULL will be filled in for these values. After all, top 1 (with or without the parentheses) returns only one row.
When you run it returning multiple rows, presumably there are matches. For the rows that match, the corresponding values are put it. This is the way that left outer join works.
Gordon's answer is correct as to why I was getting a few rows when removing top and none when I had it. The subquery in question was returning all the rows in the InventTrans table (5 million+) so when I used top, it was just getting the first row which didn't have anything. I realized this was the case when I was trying random high values (e.g 50000) in the TOP clause.
The ultimate fix was to change the left outer joins on the C and D subqueries to Cross Apply, and then change the where clauses to better filter the table (e.g itt.itemid = a.itemid and invt1.inventserialid = id.inventserialid). Using that, I was able to use TOP 1 as expected.