How to get sum of pivot column as saprate column in SQL - sql

When i try to get sum of three columns as Total it gives null when one of column is null in Recieved,Claim or Issue
SELECT YarnId,
Recieve,
Issued,
Claim,
Total=Recieve+Issued
FROM
(
SELECT YarnId,Status,Bags
FROM Yarn_IssueRecieve
) as PivotData
Pivot
(
SUM(bags) for Status in (Recieve,Issued,Damage,Claim)
) as Pivoting
Following is the output

use COALESCE
Total= COALESCE (Recieve,0) + COALESCE (Issued,0)
and
SUM( COALESCE (bags,0) )

You can use ISNULL
SELECT YarnId,
Recieve,
Issued,
Claim,
Total=ISNULL(Recieve,0)+ISNULL(Issued,0)
FROM
(
SELECT YarnId,Status,Bags
FROM Yarn_IssueRecieve
) as PivotData
Pivot
(
SUM(bags) for Status in (Recieve,Issued,Damage,Claim)
) as Pivoting

In MySql or MSSQL Server, if you add any number with NULL, the result is NULL. For example-
SELECT 10 + NULL
--Result is NULL
As a result, you have handle NULL in your query to overcome the situation you are facing. You can use COALESCE for your purpose and the script should be as below-
Total=COALESCE(Recieve,0)+COALESCE(Issued,0)

Related

How to aggregate/concate strings with no duplicates in SQL Server 2019

I am very new to SQL Server and it stucks in one task related to the aggregation of data. I tried to put all information on the screen attached. Is there anyone that could support it? My current code is below, but it does not work (duplicates...). Many thanks in advance!
select distinct
material,
plant,
STRING_AGG (exceptions, ';' ),
STRING_AGG (preferential_country, ';' )
from grs
GROUP BY material, plant
Sorry, I misunderstood part of your question. This is a bit messy, but I created a function to remove the duplicates.
CREATE FUNCTION remove_duplicate (#str varchar(100))
RETURNS varchar(100) AS
BEGIN
DECLARE #result varchar(100)
SET #result = (SELECT STRING_AGG(ta.value,';') from(
SELECT DISTINCT value FROM STRING_SPLIT(#str ,';')
)as ta)
RETURN #result
END;
This is the query to create the output table where the exceptions are group together but there will be duplicates
SELECT distinct plant,
material,
CASE WHEN count( distinct(preferential_country)) > 1 THEN 'QU'
ELSE MAX(preferential_country)
END AS preferential_country,
STRING_AGG(exceptions,';') as exceptions
into new_table
FROM tableA
group by plant, material
order by plant
Lastly, you just need to use the function to remove the duplicates.
SELECT plant, material, dbo.remove_duplicate(exceptions) as exceptions from new_table
output:
plant material exceptions
plant_1 Material_1 EU01;EU02;EU03;EU05
plant_1 Material_2 EU01
plant_2 Material_1 NULL
I couldn't get it to work in db fiddle but it's working on SSMS
db fiddle

Query to show all ID's except the ones that have a specific instrument

So I have a table which looks like this:
What would be the best query to exclude every "stuknr" that has atleast 1 "saxofoon" in the "instrumentnaam" column?
To select all stuknr where there is not stuknr with a saxofoon:
SELECT *
FROM table
WHERE stuknr not in (
SELECT stuknr
FROM TABLE
WHERE INSTRUMENTNAAM = ‘saxofoon’)
;
SELECT STUNKR
FROM TABLE
WHERE INSTRUMENTNAAM != ‘saxofoon’;
Here != (or <>, which are equivalent, see this) means "not equal".
You can do this with a NOT IN sub-select
select distinct
YT.stunkr
from
YourTable YT
where YT.stunkr NOT IN ( select distinct stunkr
from YourTable
where InstrumentNaam = 'saxofoon' )
So the sub-select is getting all IDs that DO have saxofoon and the primary select/from is getting where the ID is NOT in the secondary.

How to make rows into columns in SQL

I have this table
SELECT PolicyID, ItemID, Period, Inventory1, Inventory2
FROM tblInventory
I want to convert this table into this:
The period will be converted as Column such as Inventory1 -1 and Inventory2 -1 until 4th period, per period there are two columns included: inventory1 and inventory2.
I would like to ask help on how to code this in SQL. Thank you!
To use PIVOT with your example you want to UNPIVOT the data first.
SELECT
*
FROM
(
SELECT
UP.PolicyId
, UP.ItemId
, CONCAT(UP.Inventories, '-', UP.Period) AS Inventories
, UP.Inventory
FROM
tblInventory AS TI
UNPIVOT
(
Inventory FOR Inventories IN (Inventory1, Inventory2)
) AS UP
) AS UNP
PIVOT
(
MAX(Inventory)
FOR Inventories IN
(
[Inventory1-1], [Inventory1-2], [Inventory1-3], [Inventory1-4]
, [Inventory2-1], [Inventory2-2], [Inventory2-3], [Inventory2-4]
)
) AS PVT

Multi row to a row sql

I have a table as bellow:
I want query to print output as bellow:
Note: Please, do not downvote. I know the rules of posting answers, but for such of questions there's no chance to post short answer. I posted it only to provide help for those who want to find out how to achieve that, but does not expect ready-to-use solution.
I'd suggest to read these articles:
PIVOT on two or more fields in SQL Server
Pivoting on multiple columns - SQL Server
Pivot two or more columns in SQL Server 2005
At first UNPIVOT then PIVOT. If number of rows for each Pod_ID is not always equal 3 then you need to use dynamic SQL. The basic sample:
SELECT *
FROM (
SELECT Pod_ID,
Purs + CASE WHEN RN-1 = 0 THEN '' ELSE CAST(RN-1 as nvarchar(10)) END as Purs,
[Values]
FROM (
SELECT Pod_ID,
Pur_Qty, --All columns that will be UNPIVOTed must be same datatype
Pur_Price,
CAST(ETD_Date as int) ETD_Date, -- that is why I cast date to int
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as RN
FROM YourTable
) as p1
UNPIVOT (
[Values] FOR [Purs] IN(Pur_Qty, Pur_Price, ETD_Date)
) as unpvt
) as p2
PIVOT (
MAX([Values]) FOR Purs IN (Pur_Qty,Pur_Price,ETD_Date,Pur_Qty1,Pur_Price1,ETD_Date1,Pur_Qty2,Pur_Price2,ETD_Date2)
) as pvt
Will bring you:
Pod_ID Pur_Qty Pur_Price ETD_Date Pur_Qty1 Pur_Price1 ETD_Date1 Pur_Qty2 Pur_Price2 ETD_Date2
F8E2F614-75BC-4E46-B7F8-18C7FC4E5397 24 22 20160820 400 33 20160905 50 44 20160830

Status corresponding to Minimum value

I am using SQL Server 2005. I have a table as given below. There can be multiple cancellations for each FundingID. I want to select the FundingCancellationReason corrersponding to minimum date for each funding. I wrote a query as follows. It is an SQL error
1) Could you please help me to avoid the SQL Error?
2) Is there any better logic to achieve the same?
CREATE TABLE #FundingCancellation(
[FundingCancellationID] INT IDENTITY(1,1) NOT NULL,
[FundingID] INT ,
FundingCancellationDt SMALLDATETIME ,
FundingCancellationReason VARCHAR(50)
)
SELECT FundingID,
MIN(FundingCancellationDt),
( SELECT FundingCancellationReason
FROM #FundingCancellation FC2
WHERE FC1.FundingID = FC2.FundingID
AND FC2.FundingCancellationDt = MIN(FundingCancellationDt)
) [Reason Corresponding Minimum Date]
FROM #FundingCancellation FC1
GROUP BY FundingID
-- An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
I have seen the similar approach working in a somewhat complex query. So I believe tehre will be a way to correct my query
Thanks
Lijo
This query will return the Reason (and any other columns you may want) for each minimum date for each FundingID:
SELECT FC1.FundingID, FC1.FundingCancellationDt,
FC1.FundingCancellationReason, FC1.OtherColumn1, FC1.Other...
FROM #FundingCancellation FC1
JOIN
(
SELECT FundingID, MIN(FundingCancellationDt) as 'MinDate'
FROM #FundingCancellation
GROUP BY FundingID
) AS Grouped ON (Grouped.FundingID = FC1.FundingID
AND (Grouped.MinDate = FC1.FundingCancellationDt
OR Grouped.MinDate IS NULL))
Note that if a given FundingID has more than one row with the same FundingCancellationDt (and it is the minimum), this will return ALL reasons for that minimum date.
The "OR Grouped.MinDate IS NULL" allows for null dates.
If you have duplicate minimum dates for a FundingID and you still want only one of the Reasons for each minimum, then use this:
SELECT FundingID, MinDate,
(SELECT TOP 1 FundingCancellationReason
FROM #FundingCancellation
WHERE FundingCancellationDt = Grouped.MinDate) as 'Reason'
FROM
(
SELECT FundingID, MIN(FundingCancellationDt) as 'MinDate'
FROM #FundingCancellation
GROUP BY FundingID
) AS Grouped