how to show only Y status on my query - sql

I want to show only one status in a field:
select *, ROW_NUMBER() OVER(PARTITION BY t.Docentry ORDER BY t.linealog) FILA
from (select docnum, docentry,Confirmed as confirmado,UserSign2 as usuario,ObjType as tipodoc ,UpdateDate,UpdateTS as Hora,LogInstanc as linealog
from adoc
where ObjType=17
union all
select DocNum, DocEntry,Confirmed,UserSign2,ObjType,UpdateDate,UpdateTS,99 from ordr
) as t
order by DocEntry, FILA
this give me this output:
You can see ndoc in this case 1: give me 4 rows, i just want 2,only Y, I did it with this:
with mycte as (
select *, ROW_NUMBER() OVER(PARTITION BY t.Docentry ORDER BY t.linealog) FILA
from (select docnum, docentry,Confirmed as confirmado,UserSign2 as usuario,ObjType as tipodoc ,docdate,UpdateDate,UpdateTS as Hora,LogInstanc as linealog
from adoc
where ObjType=17
union all
select DocNum, DocEntry,Confirmed,UserSign2,ObjType,docdate,UpdateDate,UpdateTS,99 from ordr
) as t
),
mycte2 as (
select m.*, coalesce(m2.confirmado,'N') confirmadoanterior from mycte m left join mycte m2 on m.fila+1=m2.fila and m.fila=1 )
select * from mycte2 where confirmado='Y' and confirmadoanterior='N'
order by docnum
I just want the line with status ' Y' coming from status 'N' In this case only the row 10.
This is the expected result:
expected result
what kind i do to filter Y status too?
thanks.

Try filter for [Confirmed] = 'Y' inside the UNION ALL query. e.g.
SELECT
*
FROM (
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY t.Docentry ORDER BY t.linealog) FILA
FROM (
SELECT
docnum
, docentry
, Confirmed AS confirmado
, UserSign2 AS usuario
, ObjType AS tipodoc
, docdate
, UpdateDate
, UpdateTS AS Hora
, LogInstanc AS linealog
FROM adoc
WHERE ObjType = 17 AND Confirmed = 'Y' --<< HERE
UNION ALL
SELECT
DocNum
, DocEntry
, Confirmed
, UserSign2
, ObjType
, docdate
, UpdateDate
, UpdateTS
, 99
FROM ordr
WHERE Confirmed = 'Y' --<< & HERE
) AS u
) AS d
ORDER BY
docnum
If this isn't what you are looking for could you please provide "sample data" and "expected result".

Related

Results of a CTE inside a subquery and row_number with a couple order by

I have a query that runs as follows:
WITH teste1 as (
SELECT
CONCAT(a.pid, a.num_ordenado) as id_despacho,
a.pid,
a.created_at,
a.nota,
a.from_id,
a.from_nome
FROM (
SELECT pid, id,
(ROW_NUMBER() over (partition by pid order by created_at)) as num_ordenado,
from_id, from_nome, nota, created_at
FROM mytable_a) as a
),
teste2 as (
SELECT
CONCAT(t.pid, t.ordenado) as id_despacho,
t.ordenado,
t.pid as id_doc,
t.data as diahora,
CONCAT
(
'Evento: ', t.evento
) as conteudo2,
'' as pasta,
t.from_id,
t.from_nome,
t.to_id,
t.to_nome
FROM
(
SELECT pid, data,
(ROW_NUMBER() over (partition by pid order by data)) as ordenado,
from_id, from_nome, to_id, to_nome, evento
FROM mytable_t) as t
)
SELECT *
FROM teste2 as t2
LEFT JOIN teste1 as t1
ON t2.id_despacho = t1.id_despacho
WHERE t2.conteudo2 <> 'Evento: Campo bloqueado' AND t2.conteudo2 <> 'Evento: Campo desbloqueado'
In each CTE, I order the ID's by datetime and then create a new ID structure on which I join by that new ID at the last query. I'm wondering how could I do to now order them again by datetime.
My questions then would be:
Can I use the results of a CTE (teste1 and teste2 tables) inside a subquery? Something like this (not working)
SELECT
t2.id_despacho,
t2.id_doc,
t2.diahora,
t2.conteudo2,
t1.id_despacho,
t1.created_at,
t1.nota,
(ROW_NUMBER() OVER (PARTITION BY id_doc ORDER BY diahora, created_at)) AS ordenado_final
FROM
(SELECT *
FROM teste2 AS t2
LEFT JOIN teste1 AS t1 ON t2.id_despacho = t1.id_despacho
WHERE t2.conteudo2 <> 'Evento: Campo bloqueado'
AND t2.conteudo2 <> 'Evento: Campo desbloqueado')
Does that ROW_NUMBER() work like that? Can I order by two different columns?
(ROW_NUMBER() OVER (PARTITION BY id_doc
ORDER BY diahora, created_at)) AS ordenado_final

Rotation of table1 rows for given date range based on each employee

I need one small help in understanding of repeating in cycle the rows from one table (RuleSetting) to my result.
Few points to remember:
For now I have only 2 setting value for emplloyee 4536, it could be 4 or 5 as well..
SettingId rotating after every 7 days because in RuleSetting Table I have mentioned WeekOffFrequency = 7 for employee 4536
Instead of 99 it should repeat between settingIds 1,2
It should work for all employee
SQL Fiddler link:
http://sqlfiddle.com/#!18/9eecb/92011
I have attached the screenshot so that I can explain my requirement more clearly.
Note:
Records/Rows in RuleSetting table is not fixed... employee can have nth number of settings...
but RuleSetting.WeekOffFrequency value will be always same for employee
Please ask me if thre is any doubt...
I implemented it as follows.
Here
ExpandRuleSettings(add): Expand rows of RuleSettings to number of WeekOffFrequency each SettingId of employee.
NumberOfRotate(add): Get number of rotate (number of all SettingId of each employee).
EmployeeDates(change): Allocate rotated Id for date each employee.
EmployeeWeekOffFrequency(change): Join the tables EmployeeDates and ExpandRuleSettings on matching EmployeeID and Id.
DECLARE #sdate date = '2020-09-10', #edate date = '2020-09-28'
;with dates_CTE (RosterDate) as (
select #sdate
Union ALL
select DATEADD(day, 1, RosterDate)
from dates_CTE
where RosterDate < #edate
),
-- Expand rows of RuleSettings to number of WeekOffFrequency each SettingId of employee.
ExpandRuleSettingsWork as (
SELECT 0 AS IdForSettingId, SettingId, EmployeeID, ShiftPattern, WeekOffFrequency FROM #RuleSettings
UNION ALL
SELECT IdForSettingId+1, SettingId, EmployeeID, ShiftPattern, WeekOffFrequency FROM ExpandRuleSettingsWork
WHERE IdForSettingId+1 < WeekOffFrequency
),
ExpandRuleSettings as (
SELECT
ROW_NUMBER() OVER(PARTITION BY EmployeeID ORDER BY SettingId,IdForSettingId)-1 AS Id,
* FROM ExpandRuleSettingsWork
),
-- SELECT * FROM ExpandRuleSettings ORDER BY EmployeeID,SettingId,Id
-- Get number of rotate (number of all SettingId of each employee).
NumberOfRotate as (
SELECT EmployeeID, COUNT(EmployeeID) AS Num FROM ExpandRuleSettings GROUP BY EmployeeID
),
-- SELECT * FROM NumberOfRotate
EmployeeDates as (
SELECT
(ROW_NUMBER() over (partition by EmployeeId order by RosterDate) - 1) % Num as Id,
EmployeeID,
RosterDate
FROM dates_CTE
CROSS APPLY NumberOfRotate
)
--select * from EmployeeDates
--order by EmployeeID , RosterDate
,
EmployeeWeekOffFrequency as (
SELECT ed.*, er.SettingId
FROM EmployeeDates as ed INNER JOIN ExpandRuleSettings as er
ON ed.EmployeeID=er.EmployeeID AND
ed.Id = er.Id
)
SELECT * FROM EmployeeWeekOffFrequency
I have slightly modified your query and added RuleSettingsModified and NewRotateSettingId.
Please check if that works fine for you.
RuleSettingsModified AS
(
SELECT Row_number() OVER (PARTITION BY rs.EmployeeID ORDER BY (SELECT NULL)) rn, rs.EmployeeID, rs.WeekOffFrequency
FROM #RuleSettings rs
)
(Id / (SELECT DISTINCT WeekOffFrequency FROM #RuleSettings WHERE EmployeeID = ed.EmployeeID))%(SELECT count(1) FROM RuleSettingsModified rsm WHERE rsm.EmployeeID = ed.EmployeeID)+1 AS NewRotateSettingId
;with dates_CTE (RosterDate) as (
select #sdate
Union ALL
select DATEADD(day, 1, RosterDate)
from dates_CTE
where RosterDate < #edate
),
EmployeeDates as (
SELECT
ROW_NUMBER() over (partition by EmployeeId order by RosterDate) - 1 as Id,
EmployeeID,
RosterDate
FROM dates_CTE
CROSS APPLY (SELECT DISTINCT EmployeeId from #RuleSettings)as cs
),
RuleSettingsModified AS
(
SELECT Row_number() OVER (PARTITION BY rs.EmployeeID ORDER BY (SELECT NULL)) rn, rs.EmployeeID, rs.WeekOffFrequency
FROM #RuleSettings rs
)
,
EmployeeWeekOffFrequency as (
SELECT *,
Id / (SELECT DISTINCT WeekOffFrequency from #RuleSettings where EmployeeID = ed.EmployeeID)+ 1 as WeekOffFrequency,
(
CASE
WHEN
(
Id / (SELECT DISTINCT WeekOffFrequency FROM #RuleSettings WHERE EmployeeID = ed.EmployeeID)
)
<
(SELECT count(1) FROM #RuleSettings WHERE EmployeeID = ed.EmployeeID)
THEN
(
SELECT SettingId FROM #RuleSettings WHERE EmployeeID = ed.EmployeeID
AND SettingId = ((Id / (SELECT DISTINCT WeekOffFrequency FROM #RuleSettings
WHERE EmployeeID = ed.EmployeeID )) + 1 )
)
ELSE 99
END
) as RotateSettingId,
(Id / (SELECT DISTINCT WeekOffFrequency FROM #RuleSettings WHERE EmployeeID = ed.EmployeeID))%(SELECT count(1) FROM RuleSettingsModified rsm WHERE rsm.EmployeeID = ed.EmployeeID)+1 AS NewRotateSettingId
from EmployeeDates as ed
)
SELECT * FROM EmployeeWeekOffFrequency
Please see complete code here.

Find Top Most AND Lowest In a Table's Group Column

I have a table and there are 4 fields in it, ID, Price, QTY, Ratting and Optional [Position].
I have all the records Grouped By Columns [Qty,Ratting]
I have to define the position of groupwise and store that Position into Optional column.
For better understanding I have added an image with data in table:
On the basis of QTY in Each Rating I have to Mark Top3, Bottom3 and Rest of them as remaining.
I am not getting how to do it.
Can anybody suggest me how to do it?
So far what I've tried is:
Declare #RankTable TABLE
(
ID INT,
Price Decimal (10,2),
Qty INT,
Ratting INT
)
INSERT INTO #RankTable
SELECT 1,10,15,1
UNION ALL
SELECT 2,11,11,1
UNION ALL
SELECT 3,96,10,1
UNION ALL
SELECT 4,96,8,1
UNION ALL
SELECT 5,56,7,1
UNION ALL
SELECT 6,74,5,1
UNION ALL
SELECT 7,93,4,1
UNION ALL
SELECT 8,98,2,1
UNION ALL
SELECT 9,12,1,1
UNION ALL
SELECT 10,32,80,2
UNION ALL
SELECT 11,74,68,2
UNION ALL
SELECT 12,58,57,2
UNION ALL
SELECT 13,37,43,2
UNION ALL
SELECT 14,79,32,2
UNION ALL
SELECT 15,29,28,2
UNION ALL
SELECT 16,46,17,2
UNION ALL
SELECT 17,86,13,2
UNION ALL
SELECT 19,75,110,3
UNION ALL
SELECT 20,27,108,3
UNION ALL
SELECT 21,38,104,3
UNION ALL
SELECT 22,87,100,3
UNION ALL
SELECT 23,47,89,3
DECLARE #PositionGroup VARCHAR(1)
SELECT *,ISNULL(#PositionGroup,'') AS Position FROM #RankTable
You can try this:
SELECT ID
,Price
,Qty
,Ratting
,CASE WHEN RowID >= 1 AND RowID <= 3
THEN 0
ELSE CASE WHEN RowID > Total - 3 THEN 1 ELSE 2 END END AS Position
FROM (SELECT ID
,Price
,Qty
,Ratting
,COUNT(*) OVER(PARTITION BY Ratting) AS Total
,ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) AS RowID
,ISNULL(#PositionGroup,'') AS Position
FROM #RankTable) AS T
Use Window Function. Try this.
;WITH cte
AS (SELECT *,
Row_number()OVER(partition BY rating ORDER BY id) rn,
count(id)OVER(partition BY rating) mx
FROM #RankTable)
SELECT ID,
Price,
Qty,
Rating,
mx - rn,
CASE WHEN rn IN ( 1, 2, 3 ) THEN 0
WHEN mx - rn IN( 0, 1, 2 ) THEN 1
ELSE 2
END position
FROM cte
try this as well.
;WITH cte AS
(
SELECT MAX(Row) [Max],
MIN(Row) [Min],
LU.Ratting
FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) Row
FROM #RankTable)LU
GROUP BY LU.Ratting
)
SELECT ID,
R.Price,
R.Qty,
cte.Ratting,
CASE WHEN (Row - Min) <= 2 THEN 0 WHEN (Max - Row) <= 2 THEN 1 ELSE 2 END Position
FROM cte
JOIN (
SELECT Ratting,
ID,
Price,
Qty,
ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) [Row]
FROM #RankTable
) R ON R.Ratting = cte.Ratting
Result:

Minimum of the maximum values

Consider the below results
Datetime1 DateTime2 Customer
2013-06-19 2011-03-30 IP003779
2014-04-24 2011-03-30 IP003779
2011-03-30 2009-03-18 IP003779
i need to select the minimum of the first column out of the maximums of the second column.
-> 2013-06-19
I'm having a hard time figuring out the query, combining min and max. any thoughts?
Something like this ought to do, I think, to find the min of the max for each customer:
select Customer = t.Customer ,
DateTime2_Max = t.dt2Max ,
DateTime1_Min = min( x.DateTime1 )
from ( select Customer = Customer ,
dt2Max = max( DateTime2 )
from some_table
group by Customer
) t
join some_table x on x.Customer = t.Customer
and x.DateTime2 = t.dt2Max
group by t.Customer ,
t.dt2Max
If you want to look at the table overall, then it gets simpler:
select DateTime2_Max = t.dt2Max ,
DateTime1_Min = min( x.DateTime1 )
from ( select dt2Max = max( DateTime2 )
from some_table
) t
join some_table x on x.DateTime2 = t.dt2Max
group by t.dt2Max
You could also use windowing functions. Broken out by customer, it looks something like:
select *
from ( select * ,
rank = row_number() over (
partition by Customer
order by DateTime2 desc ,
DateTime1 asc
)
) t
where t.rank = 1
order by 1,2,3
And again, simpler if you look at the table as a whole:
select top 1 *
from ( select * ,
rank = row_number() over (
order by DateTime2 desc ,
DateTime1 asc
)
) t
where t.rank = 1
I think this is what you want:
select top 1 *
from table t
order by DateTime2 desc, DateTime1 asc;
Edit:
If you need to do this for all customers, use row_number():
select t.*
from (select t.*,
row_number() over (partition by customer order by datetime2 desc, datetime1 asc) as seqnum
from table t
) t
where seqnum = 1;

Update entry(ies) in Oracle table using temporary column

How can I update the a.age and b.age to 32 for all the results obtained by the below query.the temp column is "CID" as shown in below example
select *
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE
where date = '26-jULY-2012'))a
RIGHT join (select *
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE2
where date = '26-jULY-2012')))b
on a.CID=b.CID
and a.CUST_NAME=b.CUST_NAME
ORDER BY a.CUST_NAME,A.CID,a.COLUMNB;
update sometable
set age = 32
where cid in (
select a.cid
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE
where date = '26-jULY-2012'))a
RIGHT join (select *
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE2
where date = '26-jULY-2012')))b
on a.CID=b.CID
and a.CUST_NAME=b.CUST_NAME
)
;
update sometable2
set age = 32
where cid in (
select b.cid
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE
where date = '26-jULY-2012'))a
RIGHT join (select *
from (SELECT ROW_NUMBER()
OVER (PARTITION BY CUST_NAME ORDER BY CUST_NAME) AS CID,CUST_NAME,AGE,CITY,COLUMNB
FROM (select CUST_NAME,AGE,CITY,COLUMNB
from SOMETABLE2
where date = '26-jULY-2012')))b
on a.CID=b.CID
and a.CUST_NAME=b.CUST_NAME
)
;