Concat in Firebird - If one field is NULL all Content is NULL how to avoid? [duplicate] - concatenation

This question already has answers here:
Concatenate with NULL values in SQL
(8 answers)
SQL using If Not Null on a Concatenation
(9 answers)
Firebird date concatention change date format
(1 answer)
Closed 1 year ago.
How does one avoid creating a null field when doing a concat with a field that is null in Firebird.
with data as ( select article_name || ' STK:' || cast(quantity as integer) || NOTES as quantity ,PREORDER_ID as PID from preorder_item )
SELECT PREORDER.NAME ,PREORDER.DELIVERY_DATE ,LIST(DATA.QUANTITY, ' | ')
FROM PREORDER
INNER JOIN DATA ON PREORDER.ID =
DATA.PID GROUP by PREORDER.NAME ,PREORDER.DELIVERY_DATE
In all the fields were my NOTES are NULL the whole content is null how can I work around this and only add the notes information when it is available.
I already tried something like
with comments as (select NOTES as NOTES,PREORDER_ID as PID FROM PREORDER_ITEM where NOTES is not NULL)
with data as ( select article_name || ' STK:' || cast(quantity as integer) as quantity ,PREORDER_ID as PID from preorder_item )
SELECT PREORDER.NAME ,PREORDER.DELIVERY_DATE ,LIST(DATA.QUANTITY, ' | ')
FROM PREORDER
INNER JOIN DATA ON PREORDER.ID = DATA.PID
INNER JOIN COMMENTS ON PREORDER.ID = COMMENTS.PID
GROUP by PREORDER.NAME ,PREORDER.DELIVERY_DATE

You can take a look to SQL function COALESCE or NULLIF which allow you to transform null value
COALESCE( Expr1, Expr2, Expr3, ... )
NULLIF (<exp1>, <exp2>)

Related

Filtering down SQL To one value? [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 1 year ago.
I'm writing a query for SAP B1,using Microsoft SQL Server Management Studio 17.
I am wanting to return the "MIN" DocDate, but show the field "ShipDate" alongside it, with only one result...
SELECT T0.ItemCode,
T3.ShipDate AS 'Next Date',
MIN(T3.DocDate) AS 'OrderDate'
FROM OITM T0
LEFT OUTER JOIN POR1 T3 ON T0.ItemCode = T3.ItemCode
WHERE T3.LineStatus = 'O' AND T3.ShipDate > GETDATE()
Group By T0.Itemcode, T3.ShipDate
This returns the following results;
ItemCode
ShipDate
OrderDate
VT3021026
2021-05-14
2021-05-04
VT3021026
2021-06-01
2021-05-10
This is an example of what one single item is returning, however I want to return only one value for each item. Almost like a "TOP 1" for each individual item. (obviously top 1 won't work in the overall select clause because it will be required to produce a list of multiple items)
If I understand you correctly, then this code will solve the problem.
DECLARE #date datetime2 = GETDATE();
WITH T(ItemCode, OrderDate) AS
(
SELECT
T0.ItemCode,
MIN(T3.DocDate) AS 'OrderDate'
FROM OITM T0
LEFT JOIN POR1 T3
ON T0.ItemCode = T3.ItemCode
WHERE T3.LineStatus = 'O'
AND T3.ShipDate > #date
GROUP BY T0.Itemcode, T3.ShipDate
)
SELECT T.ItemCode,
T4.ShipDate AS 'Next Date',
T.OrderDate
FROM T
LEFT JOIN POR1 T4
ON T.[OrderDate] = T4.DocDate
AND T.ItemCode = t4.ItemCode;

How can we use LAG() in SQL server 2008 R2? [duplicate]

This question already has answers here:
Alternate of lead lag function in SQL Server 2008
(3 answers)
Closed 3 years ago.
SELECT
CASE
WHEN ser.[Department Name] = LAG(SER.[Department Name]) OVER (ORDER BY SER.[Department Name]) THEN ''
ELSE SER.[Department Name]
END [Department Name] from department
You can use APPLY :
SELECT (CASE WHEN d.[Department Name] = Prev_Dept
THEN '' ELSE d.[Department Name]
END) AS DepartmentName
FROM department d OUTER APPLY
( SELECT TOP (1) d1.[Department Name] AS Prev_Dept
FROM department d1
WHERE d1.? < d.?
ORDER BY ? DESC
) AS Pd;
? indicates identify column that identifies unique sequence of data.

SQL server syntax 1

with cte4 as
(
Select a.*,(a.ADV_ART+b.ADV_ART) as A_ART
from #Temp1 a
left join #Temp1 as b
on (a.CHAT_ID = b.CHAT_ID) and (a.N = b.N + 1)
where a.Category = 2 and b.Category = 2
)
UPDATE cte4
Set ADV_ART = A_ART;
In this query (a.ADV_ART+b.ADV_ART) is giving null. Please help.
If they are strings, try: coalesce(a.ADV_ART,'')+coalesce(b.ADV_ART,'')
If they are numbers, try: coalesce(a.ADV_ART,0)+coalesce(b.ADV_ART,0)
Whenever you add or concatenate a null value, the result is always null. One of your values is returning null, so you can use isnull(ValueThatMightBeNull,ReplaceWithThisValue)
or coalesce(ValueThatMightBeNull,ReplaceWithThisValue) to return a different value instead of null.
Reference:
isnull() - msdn
coalesce() - msdn

How to combine fields from 2 columns to create a "matrix"?

I have a logging table in my application that only logs changed data, and leaves the other columns NULL. What I'm wanting to do now is create a view that takes 2 of those columns (Type and Status),
and create a resultset that returns the Type and Status on the entry of that log row, assuming that either one or both columns could be null.
For example, with this data:
Type Status AddDt
A 1 7/8/2013
NULL 2 7/7/2013
NULL 3 7/6/2013
NULL NULL 7/5/2013
B NULL 7/4/2013
C NULL 7/3/2013
C 4 7/2/2013
produce the resultset:
Type Status AddDt
A 1 7/8/2013
A 2 7/7/2013
A 3 7/6/2013
A 3 7/5/2013
B 3 7/4/2013
C 3 7/3/2013
C 4 7/2/2013
From there I'm going to figure out the first time in these results the Type and Status meet certain conditions, such as a Type of B and Status 3 (7/4/2013) and ultimately use that date in a calculation, so performance is a huge issue with this.
Here's what I was thinking so far, but it doesn't get me where I need to be:
SELECT
Type.TypeDesc
, Status.StatusDesc
, *
FROM
jw50_Item c
OUTER APPLY (SELECT TOP 10000 * FROM jw50_ItemLog csh WHERE csh.ItemID = c.ItemID AND csh.StatusCode = 'OPN' ORDER BY csh.AddDt DESC) [Status]
OUTER APPLY (SELECT TOP 10000 * FROM jw50_ItemLog cth WHERE cth.ItemID = c.ItemID AND cth.ItemTypeCode IN ('F','FG','NG','PF','SXA','AB') ORDER BY cth.AddDt DESC) Type
WHERE
c.ItemID = #ItemID
So with the help provided below, I was able to get where I needed. Here is my final solution:
SELECT
OrderID
, CustomerNum
, OrderTitle
, ItemTypeDesc
, ItemTypeCode
, StatusCode
, OrdertatusDesc
FROM
jw50_Order c1
OUTER APPLY (SELECT TOP 1 [DateTime] FROM
(SELECT c.ItemTypeCode, c.OrderStatusCode, c.OrderStatusDt as [DateTime] FROM jw50_Order c WHERE c.OrderID = c1.OrderID
UNION
select (select top 1 c2.ItemTypeCode
from jw50_OrderLog c2
where c2.UpdatedDt >= c.UpdatedDt and c2.ItemTypeCode is not null and c2.OrderID = c.OrderID
order by UpdatedDt DESC
) as type,
(select top 1 c2.StatusCode
from jw50_OrderLog c2
where c2.UpdatedDt >= c.UpdatedDt and c2.StatusCode is not null and c2.OrderID = c.OrderID
order by UpdatedDt DESC
) as status,
UpdatedDt as [DateTime]
from jw50_OrderLog c
where c.OrderID = c1.OrderID AND (c.StatusCode IS NOT NULL OR c.ItemTypeCode IS NOT NULL)
) t
WHERE t.ItemTypeCode IN ('F','FG','NG','PF','SXA','AB') AND t.StatusCode IN ('OPEN')
order by [DateTime]) quart
WHERE quart.DateTime <= #FiscalPeriod2 AND c1.StatusCode = 'OPEN'
Order By c1.OrderID
The union is to bring in the current data in addition to the log table data to create the resultset, since the current data maybe what meets the conditions required. Thanks again for the help guys.
Here is an approach that uses correlated subqueries:
select (select top 1 c2.type
from jw50_Item c2
where c2.AddDt >= c.AddDt and c2.type is not null
order by AddDt
) as type,
(select top 1 c2.status
from jw50_Item c2
where c2.AddDt >= c.AddDt and c2.status is not null
order by AddDt
) as status,
(select AddDt
from jw50_Item c
If you have indexes on jw50_item(AddDt, type) and jw50_item(AddDt, status), then the performance should be pretty good.
I suppose you want to "generate a history": for those dates that has some data missing, the next available data should be set.
Something similar should work:
Select i.AddDt, t.Type, s.Status
from Items i
join Items t on (t.addDt =
(select min(t1.addDt)
from Items t1
where t1.addDt >= i.addDt
and t1.Type is not null))
join Items s on (s.addDt =
(select min(s1.addDt)
from Items s1
where s1.addDt >= i.addDt
and s1.status is not null))
Actually I'm joining the base table to 2 secondary tables and the join condition is that we match the smallest row where the respective column in the secondary table is not null (and of course smaller than the current date).
I'm not absolutely sure that it will work, since I don't have an SQL Server in front of me but give it a try :)

How to merge a select statement with a calculated value as new columns? [duplicate]

This question already has answers here:
How to merge a select statement with a new dynamic values as columns?
(4 answers)
Closed 9 years ago.
In my sql server code, I have this select statement
select distinct
a.HireLastName,
a.HireFirstName,
a.HireID,
a.Position_ID,
a.BarNumber,
a.Archived,
a.DateArchived,
b.Position_Name
from NewHire a
join Position b on a.Position_ID = b.Position_ID
join WorkPeriod c on a.hireID = c.HireID
where a.Archived = 0 and c.InquiryID is not null
order by a.HireID DESC, a.HireLastName, a.HireFirstName
And I want to add a new column to it. However this column is not a column from a table, its just used to store a float from a calculation I make from existing columns.
The number I get is calculated like this:
#acc is the a.HireID from the above select statement.
CAST((select COUNT(*) from Hire_Response WHERE HireID = #acc AND (HireResponse = 0 OR HireResponse = 1)) as FLOAT) /
CAST((select COUNT(*) from Hire_Response WHERE HireID = #acc) as FLOAT)
How can I do this?
Thanks.
You can use the code that GBN did for you on your other question as a sub-query
select distinct
a.HireLastName,
a.HireFirstName,
a.HireID,
a.Position_ID,
a.BarNumber,
a.Archived,
a.DateArchived,
b.Position_Name,
d.percentage
from NewHire a
inner join Position b on a.Position_ID = b.Position_ID
inner join WorkPeriod c on a.hireID = c.HireID
left join (select NH.HireID, ISNULL(1E0 * COUNT(CASE WHEN HireResponse IN (0,1) THEN HR.HireID END) / NULLIF(COUNT(HR.HireID), 0) , 0) AS percentage
from NewHire NH LEFT JOIN Hire_Response HR ON NH.HireID = HR.HireID
group by NH.HireID) d
ON a.HireID = d.HireID
where a.Archived = 0 and c.InquiryID is not null
order by a.HireID DESC, a.HireLastName, a.HireFirstName
... this will add the column percentage to your current query. This could probably be improved, but it should give you a god idea of how you can bring the results of your questions together.

Resources