In this simple Pivot Example (T-SQL), I am trying to replace the NULL with 0. I have tried all the suggestions that I found but still getting NULL. How do I replace the NULL value in a PIVOT with 0
select *
from
(
select ISNULL([vendid],0)as [vendid],isnull(origdocamt,0)as origdocamt
from APDoc
) X
pivot
(sum(origdocamt) for vendid in ([AAA],[BBB])) As P
Output
AAA BBB
45800 NULL
You will want to use IsNull or Coalesce to perform the replacement of null in the final select:
select
[AAA] = IsNull([AAA], 0),
[BBB] = IsNull([BBB], 0)
from
(
select [vendid],
origdocamt
from APDoc
) X
pivot
(
sum(origdocamt)
for vendid in ([AAA],[BBB])
) As P
The NULL's you are seeing are because of the new values:
select ISNULL([AAA],0) as [AAA], ISNULL([BBB],0) as [BBB]
from
(
select ISNULL([vendid],0)as [vendid],isnull(origdocamt,0)as origdocamt
from APDoc
) X
pivot
(sum(origdocamt) for vendid in ([AAA],[BBB])) As P
Related
I'm updating sitename as below. But then I need to utilize the levelindex from a in another query which is getting joined with the first query.
update billofquantity_temp a
set sitename = b.boqitemname
from (
select a.* from
(
select levelindex,productno,boqitemid,boqitemname,fileid from billofquantity_temp
where productno ='' and levelindex !='' //first query
) a
join
(
select distinct substring(levelindex,1,length(a.levelindex) lblindex from billofquantity_temp
where boqitemid !='' and levelindex !=''
and length(levelindex) > 2
) b on a.levelindex=b.lblindex // second query
) b
where a.levelindex=b.levelindex;
I need to use the a.levelindex in second query to get the substrings of the it's length. But this throws error invalid reference to FROM-clause entry for table "a"
Is there any other way to use the column from query 1 in 2 while joining them?
Update:
Based on kims answer, I could get the selection done but there is error syntax error at c.a.levelindex. There error is thrown even with c.levelindex.
A slight modification to the query made no errors but the intened update doesn't happen. Instead only one particular values is updated. Below is the updated query to remove errors
update billofquantity_temp d
set sitename = c.boqitemname
from (
select * from (
select levelindex, boqitemname from billofquantity_temp
where productno = '' and levelindex != '' -- first query
) a
join (
select distinct levelindex lblindex from billofquantity_temp
where boqitemid != '' and levelindex != '' and length(levelindex) > 2 ) b
on a.levelindex = substring(b.lblindex, 1, length(a.levelindex)) -- second query
) c
where d.levelindex = c.lblindex;
Move the computation of lblindex outside the sub-select to the on clause:
update billofquantity_temp d
set sitename = c.boqitemname
from (
select *
from (
select levelindex, boqitemname
from billofquantity_temp
where productno = '' and levelindex != '' -- first query
) a
join (
select distinct levelindex
from billofquantity_temp
where boqitemid != '' and levelindex != '' and length(levelindex) > 2
) b
on a.levelindex = substring(b.levelindex, 1, length(a.levelindex)) -- second query
) c
where d.levelindex = c.a.levelindex
;
I've also used c and d to avoid confusion from using a and b twice, added a missing ), and removed unused fields from select.
i have a function that return missing documentno from a table but lenght of left part of data in column documentno is passed manually and right part has some ambiguities.
Now i want a function that will read the data from a column (documentno) and return the missing documentno dynamically.
my query :
CREATE TABLE c_order (
"order_id" VARCHAR(22),
"documentno" VARCHAR(20)
);
INSERT INTO c_order
("order_id", "documentno")
VALUES
('100001120', 'AGB/2021/02050'),
('100001124' ,'AGB/2021/02055'),
('100001120', 'PROFS/2021/02056'),
('100001124' ,'PROF/2021/02060'),
('100001125' ,'PROF/2021/02065'),
('100001120', 'PROFS/2020/02050_A'),
('100001124' ,'PROFS/2020/02055_A'),
('100001120', 'PROFS/2021/02056'),
('100001124' ,'PROFSS/2021/0206010'),
('100001125' ,'PROFSS/2021/0206020')
with cte as (
select left(documentno,13) lpart,
regexp_replace(split_part(documentno, '/', 3), '[^0-9]', '', 'g')::int as num
from c_order
), minmax as (
select lpart, min(num) minpart, max(num) maxpart
from cte
group by lpart
)
select lpart||t.doc_no as missing_doc_no
from minmax m
cross join generate_series(minpart, maxpart) as t(doc_no)
where not exists (select *
from c_order c
where regexp_replace(split_part(c.documentno, '/', 3), '[^0-9]', '', 'g')::int = t.doc_no)
my fiddle : https://dbfiddle.uk/?rdbms=postgres_12&fiddle=0d3a6a647c6ef2a9063c7f3289446998
How can I do that?
i didn't write the whole solution since you already got it right, but here is how to get the last numeric part dynamically using regular expression :
select
substring(documentno, '\w*\/\d*\/') constantpart ,
max(substring(regexp_replace(documentno, '\w*\/\d*\/', '') from '\d*'))::int Maxnumericpart,
min(substring(regexp_replace(documentno, '\w*\/\d*\/', '') from '\d*'))::int Minnumericpart
from c_order co
group by constantpart
ok , here is the full solutions:
select tt.constantpart || LPAD(t.doc_no::text,ll,'0') missingdocumentNo
from
(select
substring(documentno, '\w*\/\d*\/') constantpart ,
max(substring(regexp_replace(documentno, '\w*\/\d*\/', '') from '\d*'))::int Maxnumericpart,
min(substring(regexp_replace(documentno, '\w*\/\d*\/', '') from '\d*'))::int Minnumericpart,
length(min(substring(regexp_replace(documentno, '\w*\/\d*\/', '') from '\d*'))) ll
from c_order co
group by constantpart
) tt
cross join generate_series(Minnumericpart, Maxnumericpart) as t(doc_no)
where not exists (
select 1
from c_order co2
where substring(co2.documentno, '\w*\/\d*\/\d*') = tt.constantpart || LPAD(t.doc_no::text,ll,'0')
)
order by missingdocumentNo;
db<>fiddle here
I have a column in a postgres database which logs search querystrings for a page on our website.
The column contains data like
"a=2&b=4"
"a=2,3"
"b=4&a=3"
"a=4&a=3"
I'd like to work out the frequency of each value for a certain parameter (a).
value | freq
------|------
3 | 3
2 | 2
4 | 1
Anyway to do this in a single SQL statement?
Something like this:
with all_values as (
select string_to_array(split_part(parameter, '=', 2), ',') as query_params
from the_table d,
unnest(string_to_array(d.querystring, '&')) as x(parameter)
where x.parameter like 'a%'
)
select t.value, count(*)
from all_values av, unnest(av.query_params) as t(value)
group by t.value
order by t.value;
Online example: http://rextester.com/OXM67442
try something like this :
select data_value,count(*) from (
select data_name,unnest(string_to_array(data_values,',')) data_value from (
select split_part(data_array,'=',1) data_name ,split_part(data_array,'=',2) data_values from (
select unnest(string_to_array(mydata,'&')) data_array from mytable
) a
) b
) c where data_name='a' group by 1 order by 1
Assuming tha table that keeps the counts is called paramcount:
WITH vals(v) AS
(SELECT regexp_replace(p, '^.*=', '')
FROM regexp_split_to_table(
'b=4&a=3,2',
'&|,'
) p(p)
)
INSERT INTO paramcount (value, freq)
SELECT v, 1 FROM vals
ON CONFLICT (value)
DO UPDATE SET freq = paramcount.freq + 1
WHERE paramcount.value = EXCLUDED.value;
get csv integer after 'a='
split that to numbers
stat values
select v, count(*) from (
SELECT c,unnest(string_to_array(unnest(regexp_matches(c,'a=([0-9,]+)','g')),',')) as v FROM qrs
) x group by v;
Parametrize:
WITH argname(aname) as (values ('a'::TEXT))
select v, count(*) from (SELECT c,unnest(string_to_array(unnest(regexp_matches(c,aname||'=([0-9,]+)','g')),',')) as v FROM qrs,argname) x group by v;
I need a query based on an exclusive Or statement for this I try using the case but I won't get a result in case of Null...
...
and b.[U_Periode] = CASE
when (b.U_Periode= #period) then #period
when (b.U_Periode is NULL ) then null
end
...
The Case that won't be catched is... if B.U_Status is null and b.U_Periode is null.
If the var Periode match the Value and the U_Status = 0 or 1
the only way getting this working for me was this:
...
and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
are there any other better solutions for this?
Best regards
Oliver
Okay... here is my Problem
Table1
InsID ContractID
1 1
2 1
Table2
ID insid Period Status Count
1 1 null null 100
2 1 30.09.2015 1 500
3 2 null null 100
4 2 30.09.2015 1 500
Case '31.08.2015'
in total Value should be 200
in case of '30.09.2015'
the Value should be 1.000
XOR /OR will do the same in this case.
Value case '31.08.2015' = 200
value Case ' 30.09.2015 = 2200
So this is somesing like a subquery
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID] in(select... but here I should have an if statement...
If there are results matching the Date join this
If not than join the result NULL is matching to periode...
Okay.. here is the complete query
the Table2 with the Date of 31.08.2015 should have one Record that include
B_STATUS = Null and B.Preiode = null and there is no available record with the U_Periode '31.08.2015' and a Staus ...
with a date of 30.09.2015
there is a Record matching U_Period = '30.09.2015' in this case the Record with U_Period=null should not effect the result...
Declare #period as varchar(20)= '31-08-2015 00:00:00'
declare #Customer as Varchar(15)='12345'
declare #Contract as varchar(30) = '123'
declare #test as varchar(1) = null
select SUM(cast(K.U_Count as decimal))as counter, K.U_CounterTyp
from [dbo].[Table1] a
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID]=a.[insID] and b.[U_ObjectType]in ('5','1') and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
where a.[customer] =#Customer and a.[Status]='A' and a.[U_ContrCount]='1'
and a.[manufSN] in(
select c.[ManufSN] from [dbo].[Table4] c
inner join [dbo].[OCTR]d on d.[ContractID] = c.[ContractID]
where c.[ManufSN]=a.[manufSN]
and d.[CstmrCode] = a.[customer] and d.[ContractID]=#Contract
)
group by K.U_CounterTyp
you must use the "^" operand, this is XOR operand in TSQL
expression ^ expression
the expression must return or 0 or 1...
stupid example:
WHERE (name like "stackoverflow") ^ (age > 10)
font: https://msdn.microsoft.com/en-us/library/ms190277(v=sql.105).aspx
Update for your check
WHERE (CONVERT(VARCHAR(10), a.[U_Periode], 104) = '30.08.2015') != (a.U_Periode IS NULL)
Olay here is my funktion that chek either a Date Result is there or not.
The only thing is, that the performance is not the best if I run hundreths of sentences ... foreach record (up to app. 1000) I need to query each subtable... and there are many many records in...
Anyway this is the function
CREATE FUNCTION fn_GetInsCounters(#InsId as Varchar(30), #Date as datetime)
returns datetime
as
begin
declare #count as int = 0
declare #Retruns as Datetime
set #count =
(
select count( b.Docentry)
from [dbo].[Table2]b
where b.U_Insid =#InsID
and b.U_Status <> '2'
and b.[U_ObjectType]in ('5','1')
and b.U_Periode=#Date
)
if(#count>0)
begin
set #Retruns = #date
end
else
begin
set #Retruns = '01.01.1901'
end
return #Retruns
end
if anyone gets a better idea???
Best regards
Oliver
This query gives me 2 rows but the result is presented a just 1 row. I dont understand why. I want the result as 2 rows.
SELECT *
FROM table AS S1
INNER JOIN table AS S2
ON S1.code = S2.code
WHERE S1.column1 IS NULL
AND S2.column1 IS NOT NULL
Here is the ouptput that i am expecting:
EXPECTED OUTPUT:
ID login email code column1
--------------------------------------------
96 testid1 test-Email1 XPQR NULL
97 testid1 test-Email1 XPQR P
Just a wild guess:
SELECT *
FROM table AS S1
WHERE EXISTS
( SELECT *
FROM table AS S2
WHERE ( S2.code = S1.code )
AND ( ( S1.column1 IS NULL AND S2.column1 IS NOT NULL )
OR ( S2.column1 IS NULL AND S1.column1 IS NOT NULL )
)
) ;