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]
Related
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
. . . ;
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
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
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
i have a data like this in sql table
String
914-3000-0002
03/14/2018 13:03:10
03/16/2018 13:03:10
26074
Need to convert like the below(4 columns needs to change)
task no start date end date id
914-3000-0002 | 03/14/2018 13:03:10 | 03/16/2018 13:03:10 | 26074
Try this:
DECLARE #Tab TABLE(String VARCHAR(50))
INSERT INTO #Tab VALUES ('914-3000-0002')
INSERT INTO #Tab VALUES ('03/14/2018 13:03:10')
INSERT INTO #Tab VALUES ('03/16/2018 13:03:10')
INSERT INTO #Tab VALUES ('26074')
SELECT MAX(CASE WHEN D.RN=1 THEN D.String END)[task no]
,MAX(CASE WHEN D.RN=2 THEN D.String END) [start date]
,MAX(CASE WHEN D.RN=3 THEN D.String END) [end date]
,MAX(CASE WHEN D.RN=4 THEN D.String END) [id]
FROM(
SELECT *
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))RN
FROM #Tab
)D
Output:
task no start date end date id
914-3000-0002 03/14/2018 13:03:10 03/16/2018 13:03:10 26074
In order to do this safely, you need a column that specifies the ordering. SQL tables represent unordered sets. So:
select max(case when seqnum = 1 then string end) as taskno,
max(case when seqnum = 2 then string end) as startdate,
max(case when seqnum = 3 then string end) as enddate,
max(case when seqnum = 4 then string end) as id
from (select t.*, row_number() over (order by ?) as seqnum
from t
) t;
The ? is for the ordering column. Without an ordering column, you might try to do this and the code might seem to work -- but it might break at any point.