I have data like this in a DB2 table like below.
Server Name Job ID Job Status
SERVER_A 00000001 Success
SERVER_A 00000002 Failure
SERVER_A 00000003 Success
SERVER_B 00000004 Failure
SERVER_B 00000005 Failure
SERVER_B 00000006 Failure
SERVER_C 00000007 Success
SERVER_C 00000008 Success
SERVER_C 00000009 Success
I need to display results as below.
Server Name Success Failure
SERVER_A 2 1
SERVER_B 0 3
SERVER_C 3 0
Solution 1
select ServerName,
sum(case when JobStatus='Success' then 1 else 0 end) Success,
sum(case when JobStatus='Failure' then 1 else 0 end) Failure
from yourtable
group by ServerName
Solution 3
select distinct f1.ServerName, f3.*, f4.*
from yourtable f1
inner join lateral
(
select count(*) as Success from yourtable f2
where f2.ServerName=f1.ServerName and f2.JobStatus='Success'
) f3 on 1=1
inner join lateral
(
select count(*) as Failure from yourtable f2
where f2.ServerName=f1.ServerName and f2.JobStatus='Failure'
) f4 on 1=1
Solution 2
select distinct ServerName,
(select count(*) from yourtable f2 where f2.ServerName=f1.ServerName and f2.JobStatus='Success') Success,
(select count(*) from yourtable f2 where f2.ServerName=f1.ServerName and f2.JobStatus='Failure') Failure
from yourtable f1
Solution 4
with StatServer as (
select f1.ServerName, f1.JobStatus, count(*) as nb
from yourtable f2
group by f1.ServerName, f1.JobStatus
)
select
ifnull(f1.ServerName, f2.ServerName) as ServerName,
ifnull(f1.nb, 0) as Success,
ifnull(f2.nb, 0) as Failure
from StatServer f1 full outer join StatServer f2
on f1.ServerName=f2.ServerName and f1.JobStatus='Success' and f1.JobStatus='Failure'
Related
I am trying to get the max date by account from 3 different tables and view those dates side by side. I created a separate query for each table, merged the results with UNION ALL, and then wrapped all that in a PIVOT.
The first 2 sections in the link/pic below show what I have been able to accomplish and the 3rd section is what I would like to do.
Query results by step
How can I get the results from 2 of the tables to repeat? Is that possible?
--define var_ent_type = 'ACOM'
--define var_ent_id = '52766'
--define var_dict_id = 113
SELECT
*
FROM
(
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'PERF_SUMMARY' as "TableName",
PS.DICTIONARY_ID,
to_char(MAX(PS.END_EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN PERFORMDBO.PERF_SUMMARY PS ON (PS.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND PS.DICTIONARY_ID >= 100
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'PERF_SUMMARY',
PS.DICTIONARY_ID
union all
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'POSITION' as "TableName",
0 as DICTIONARY_ID,
to_char(MAX(H.EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN HOLDINGDBO.POSITION H ON (H.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'POSITION',
1
union all
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'CASH_ACTIVITY' as "TableName",
0 as DICTIONARY_ID,
to_char(MAX(C.EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN CASHDBO.CASH_ACTIVITY C ON (C.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'CASH_ACTIVITY',
1
--ORDER BY
-- 2,3, 4
)
PIVOT
(
MAX("MaxDate")
FOR "TableName"
IN ('CASH_ACTIVITY', 'PERF_SUMMARY','POSITION')
)
Everything is possible. You only need a window function to make the value repeat across rows w/o data.
--Assuming current query is QC
With QC as (
...
)
select code, account, grouping,
--cash,
first_value(cash) over (partition by code, account order by grouping asc rows unbounded preceding) as cash_repeat,
perf,
--pos,
first_value(pos) over (partition by code, account order by grouping asc rows unbounded preceding) as pos_repeat
from QC
;
See first_value() help here: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/FIRST_VALUE.html#GUID-D454EC3F-370C-4C64-9B11-33FCB10D95EC
I need help in my query. I am trying to divide a SUM of a column with different WHERE conditions for example
SELECT
TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY') AS YR,
SUM(T1.PRICE) AS COLUMN_1
FROM TABLE_ONE T1
INNER JOIN SUB_STATUSES status ON status.SUB_ID = T1.ID
WHERE status.R_SUB_STATUS_CODE = 'COMPLETED'
AND T1.TYPE = 'COMPANY' OR T1.TYPE = 'SMALL_BUSINESS'
GROUP BY TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY')
ORDER BY TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY') DESC
DIVIDE BY
SELECT
TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY') AS YR,
SUM(T1.PRICE) AS COLUMN_1
from TABLE_ONE T1
INNER JOIN SUB_STATUSES status ON status.SUB_ID = T1.ID
WHERE status.R_SUB_STATUS_CODE = 'COMPLETED'
AND T1.TYPE = 'LOT' OR T1.TYPE = 'LAND'
GROUP BY TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY')
ORDER BY TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY') DESC
The first Column returns this :
2017 1094
2016 89
2015 95
2014 101
2013 113
2012 173
2011 191
2010 165
Use a case statement instead of a where clause. Outer query checks divide by zero.
SELECT yr, case when column_2 <> 0 then column_1/column2 else 0 end divcol
FROM (
SELECT
TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY') AS YR,
SUM(case when t1.type in ('COMPANY', 'SMALL_BUSINESS') THEN T1.PRICE ELSE 0 END) as COLUMN_1,
SUM(case when t1.type in ('LOT', 'LAND') THEN T1.PRICE ELSE 0 end) AS COLUMN_2
FROM TABLE_ONE T1
INNER JOIN SUB_STATUSES status ON status.SUB_ID = T1.ID
WHERE status.R_SUB_STATUS_CODE = 'COMPLETED'
GROUP BY TO_CHAR(PS.REPORT_PERIOD_END_DATE, 'YYYY')
)
ORDER BY yr DESC
I need the below select results to be converted into single row ,
Actual output:
ORDER POSTCODE Quantity Value
123456 AAAAA 22.78 5
123456 AAAAA 2.93 7
Expected Output:
ORDER POSTCODE AmbientQuantity Ambientvalue FVQuantity FvVAlue
123456 AAAAA 22.78 5 2.93 7
How to achieve the expected output in db2?
Following SQL will do the job:
with temp as (
select ORDER, POSTCODE, QUANTITY, VALUE,
rownumber() over (partition by ORDER, POSTCODE) as rownum
FROM mytable2
)
select ORDER, POSTCODE,
max(case when rownum = 1 Then QUANTITY end) as AMBIENTQUANTITY,
max(case when rownum = 1 Then VALUE end) as AMBIENTVALUE,
max(case when rownum = 2 Then QUANTITY end) as FVQuantity,
max(case when rownum = 2 Then VALUE end) as FVVALUE
from temp
group by ORDER, POSTCODE
Try something like this:
with tmp as (
select f0.*, rownumber() over(partition by f0.ORDER, f0.POSTCODE) rang
from your table f0
)
select
f1.ORDER, f1.POSTCODE, f1.Quantity AmbientQuantity, f1.Value Ambientvalue,
f2.Quantity FVQuantity2, f2.Value FvVAlue2,
f3.Quantity FVQuantity3, f2.Value FvVAlue3,
f4.Quantity FVQuantity4, f2.Value FvVAlue4
from tmp f1
left outer join tmp f2 on (f1.ORDER, f1.POSTCODE)=(f2.ORDER, f2.POSTCODE) and f2.rang=2
left outer join tmp f3 on (f1.ORDER, f1.POSTCODE)=(f3.ORDER, f3.POSTCODE) and f3.rang=3
left outer join tmp f4 on (f1.ORDER, f1.POSTCODE)=(f4.ORDER, f4.POSTCODE) and f4.rang=4
where f1.rang=1
I have this script:
SELECT 'pro' as descript, COUNT(*) as cnt FROM Trade.TradesMen where TradesManAccountType_Value = 2 AND HasTradeListing = 1
UNION ALL
SELECT 'std' as descript, COUNT(*) as cnt FROM Trade.TradesMen tm
INNER JOIN Membership.Members m ON m.MemberId = tm.MemberId
INNER JOIN aspnet_Membership am ON am.UserId = m.AspNetUserId
WHERE tm.TradesManAccountType_Value = 1 AND tm.HasTradeListing = 1 AND am.IsApproved = 1
UNION ALL
SELECT 'listed' as descript, COUNT(*) as cnt FROM Trade.TradesMen where HasTradeListing = 1
UNION ALL
SELECT 'all' as descript, COUNT(*) as cnt FROM Trade.TradesMen
insert into Admin.VersionHistory values(4,cnt,CURRENT_TIMESTAMP) //is NOT correct
this produces:
1 pro 32549
2 std 13096
3 listed 230547
4 all 231638
I want to add the above as rows in my table: Admin.VersionHistory which has columns VersionHistory type int auto-increment and is the ID, Version which is of type varchar(50) and a datatime stamp
thanks
(updated with new info from OP)
From the top of my head, it would look something like this.
INSERT INTO Admin.VersionHistory (Version, NumberOf, DateAndTime)
SELECT descript, CAST(cnt AS VARCHAR), SYSDATE
FROM
(
SELECT 'pro' as descript, COUNT(*) as cnt FROM Trade.TradesMen where TradesManAccountType_Value = 2 AND HasTradeListing = 1
UNION ALL
SELECT 'std' as descript, COUNT(*) as cnt FROM Trade.TradesMen tm
INNER JOIN Membership.Members m ON m.MemberId = tm.MemberId
INNER JOIN aspnet_Membership am ON am.UserId = m.AspNetUserId
WHERE tm.TradesManAccountType_Value = 1 AND tm.HasTradeListing = 1 AND am.IsApproved = 1
UNION ALL
SELECT 'listed' as descript, COUNT(*) as cnt FROM Trade.TradesMen where HasTradeListing = 1
UNION ALL
SELECT 'all' as descript, COUNT(*) as cnt FROM Trade.TradesMen
) ;
This is assuming the VersionHistoryIdcolumn is automatically seeded by the database. With each insert, an ID number will be automatically inserted.
Not sure what you want to achieve with the CURRENT_TIMESTAMP column though. I put SYSDATE as a timestamp.
The NumberOf column contains the count data. Name it as you see fit.
insert into Admin.VersionHistory
SELECT 'all', COUNT(*),current_timestamp FROM Trade.TradesMen
I am using SSMS 2008 and trying to use a HAVING statement. This should be a real simple query. However, I am only getting one record returned event though there are numerous duplicates.
Am I doing something wrong with the HAVING statement here? Or is there some other function that I could use instead?
select
address_desc,
people_id
from
dbo.address_view
where people_id is not NULL
group by people_id , address_desc
having count(*) > 1
sample data from address_view:
people_id address_desc
---------- ------------
Murfreesboro, TN 37130 F15D1135-9947-4F66-B778-00E43EC44B9E
11 Mohawk Rd., Burlington, MA 01803 C561918F-C2E9-4507-BD7C-00FB688D2D6E
Unknown, UN 00000 C561918F-C2E9-4507-BD7C-00FB688D2D6E
Jacksonville, NC 28546 FC7C78CD-8AEA-4C8E-B93D-010BF8E4176D
Memphis, TN 38133 8ED8C601-5D35-4EB7-9217-012905D6E9F1
44 Maverick St., Fitchburg, MA 8ED8C601-5D35-4EB7-9217-012905D6E9F1
The GROUP BY is going to lump your duplicates together into a single row.
I think instead, you want to find all people_id values with duplicate address_desc:
SELECT a.address_desc, a.people_id
FROM dbo.address_view a
INNER JOIN (SELECT address_desc
FROM dbo.address_view
GROUP BY address_desc
HAVING COUNT(*) > 1) t
ON a.address_desc = t.address_desc
using row_number and partition you can find the duplicate occurrences where row_num>1
select address_desc,
people_id,
row_num
from
(
select
address_desc,
people_id,
row_number() over (partition by address_desc order by address_desc) row_num
from
dbo.address_view
where people_id is not NULL
) x
where row_num>1