Pivot Rows to Column in SQL without Aggregation - sql

I'm looking to pivot multiple rows into columns. But when i use Max or Min in Pivot, its returning only one row. I want to display all the rows. Can any one help with this ?
From:
To:

You can use conditional aggregation:
select object_key,
max(case when name = 'OBJECT_NAME' then value end) as object_name,
max(case when name = 'Start Time' then value end) as start_time,
max(case when name = 'End Time' then value end) as end_time,
max(case when name = 'row_count' then value end) as row_count,
max(case when name = 'Execution Time' then value end) as execution_time
from t
group by object_key;
I'm not sure why you specify "no aggregation" in the question.
If you really have an aversion to aggregation use can use joins:
select ton.object_key, ton.value as object_name,
ts.value as start_time, te3.value as end_time,
. .
from t ton on
t ts
on ton.object_key = ts.object_key join
t te
on ton.object_key = t3.ojbect_key. join
. . . ;

Related

How to present a particular SQL queried row as columns in output

I need to present the attached output in PIC1 as the result in PIC2. The query used for generating PIC1 output in SQLDeveloper:
select subs_nm, as_of_date, run_status, (select max (tp.pr_vl)
from ual_mng.tqueue tq, ual_mng.tparams tp, ual_mng.tstatus ts
WHERE tq.tid = tp.tid AND tq.tid = ts.tid and tq.run_id = pcm.run_id and tp.pr_nm in ('TOT_RECORD_CNT')) as RECORD_COUNT
from UAL_MNG.PCM_SUBS_RUN_DTL_VW pcm where SUBS_NM='S_TS2_AQUA_A1_RLAP_DL' and AS_OF_DATE in ('2021-09-01','2021-09-02') order by run_start_dtm desc;
Appreciate all help.
If you don't need it to be dynamic (ie. it will only be two columns and you know which two months they are) you can do
select subs_nm,
max(case when as_of_date = '2021-09-01' then RECORD_COUNT else 0 end) as SEP1,
max(case when as_of_date = '2021-09-02' then RECORD_COUNT else 0 end) as SEP2,
from (
-- Your query
)
group by subs_nm
You can work out the percentage difference using the same expressions.
nb. I would always use an explicit date format mask. This might not run on a different machine / software. So use to_date('2021-09-01', 'yyyy-mm-dd')
Posting the query, which worked in the script :
select subs_nm, SEP1, SEP2, round((((SEP1-SEP2)/SEP1)*100),2) as DIFF_PER from ( select subs_nm,
max(case when as_of_date='2021-09-01' then RECORD_COUNT else '0' end) as SEP1,
max(case when as_of_date='2021-09-02' then RECORD_COUNT else '0' end) as SEP2 from (-- *Main Query*);

Find difference between two rows in sql

I have table that stores the employe info in multiple rows and it having the common name for it along with its user login time and log out time for website, and would like to achieve the result and it may contains multiple names such as (N1,N2,N3..etc)
Name,Key,Time,
N1,TotalExp,No
N1,TotalYears,5
N1,LoggedIn,10:00:00
N1,LoggedOut,20:00:00
Expected Output will like below,
N1,TotalExp,TotalYrs,LoggedDifference
N1,No,5,10
Any one help me to achieve this
Even it's a fact that the design of your database doesn't look well, you can query your data this way:
with your_data as (
select 'N1' as Name,'TotalExp' as [Key],'No' as Time union all
select 'N1','TotalYears','5' union all
select 'N1','LoggedIn','10:00:00' union all
select 'N1','LoggedOut','20:00:00'
)
select
Name,
max(case when [Key] = 'TotalExp' then Time else null end) as TotalExp,
max(case when [Key] = 'TotalYears' then Time else null end) as TotalYrs,
datediff(
hour,
max(case when [Key] = 'LoggedIn' then convert(time, Time) else null end),
max(case when [Key] = 'LoggedOut' then convert(time, Time) else null end)
) as LoggedDifference
from your_data
group by Name
You can test on here

SQL Lag and LEAD query

I need data which is in Output column. When 1st column status is P then we need value from Filled date. But once status is anything from P then we need date from last P status. Pls. let me know if i am not able to explain. Thanks in advance.
In standard SQL, you can use:
select (case when status = 'P'
then filled_dt
else lag(case when status = 'P' then filled_dt end) over (partition by mbr_id order by filled_dt ignore nulls)
end) as imputed_filled_dt
This is standard SQL; however, not all databases support ignore nulls. This probably does what you want:
select (case when status = 'P'
then filled_dt
else max(case when status = 'P' then filled_dt end) over (partition by mbr_id order by filled_dt)
end) as imputed_filled_dt

How to calculate start and end time an event in sql?

I have a table as below:
I want to calculate data in below format:
AreaID, Power_ON_Date, Power_OFF_Date, Diff_In_Minutes
Also, I need to handle:
Successive entries of same event. In case of successive entries of same event with different times, need to consider only the first occurrence of the event and ignore the others.
Merge two rows of successive OFF and ON event into 1 row to get the desired result.
You can do aggregation :
select areaid,
max(case when powerstatus = 'power on' then eventdatetime end) as Power_ON_Date,
min(eventdatetime) as Power_OFF_Date,
datediff(minute, min(eventdatetime), max(case when powerstatus = 'power on' then eventdatetime end)
) as diff_minute
from (select t.*,
sum(case when powerstatus = 'power off' then 1 else 0 end) over (partition by areaid order by eventdatetime) as grp
from table t
) t
group by areaid, grp;
Note : date_diff() is for SQL Server, however you didn't any specific database. So, the function definition may different

tSQL pivot duplicating timestamps

I have a SQL query that seems to be duplicating certain timestamps instead of correctly pivoting all the data into a single timestamp row. Am i missing something crazy?
HELP?!
SELECT
[time]
,DLPK
,IMBL
,THLD
,VEXC
,FLOW
FROM X
PIVOT
(
max([value])
FOR [tag2] IN (DLPK, IMBL, THLD, VEXC, FLOW)
) AS P
ORDER by [time]
Conditional aggregation is simpler and less error-prone:
SELECT [time],
MAX(CASE WHEN tag = 'DLPK' THEN value END) as dlpk,
MAX(CASE WHEN tag = 'IMBL' THEN value END) as imbl,
MAX(CASE WHEN tag = 'THLD' THEN value END) as thld,
MAX(CASE WHEN tag = 'VEXC' THEN value END) as vexc,
MAX(CASE WHEN tag = 'FLOW' THEN value END) as flow
FROM X
GROUP BY [time]
ORDER by [time]