Oracle: filter all rows before the ID - sql

I have a big query that brings me a lot of rows, and based on each row I use this another query as a subselect.
This subselect brings me the following result rest on Oracle:
SELECT oc3.ID_ORGAO_INTELIGENCIA,
oc3.ord,
lag(oc3.ID_ORGAO_INTELIGENCIA, 1, NULL) OVER (
ORDER BY oc3.ord) ultimo
FROM
( SELECT DISTINCT oc2.*
FROM
( SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
oc1.SG_ORGAO_INTELIGENCIA,
rownum AS ord
FROM TB_ORGAO_INTERNO oc1
WHERE oc1.DH_EXCLUSAO IS NULL START WITH oc1.ID_ORGAO_INTELIGENCIA =
-- this is a value that come from an outer select
-- If I put the value directly, like: S.ID_ORGAO_INTELIGENCIA, it does not work... I dont know why...
(SELECT sa.ID_ORGAO_INTELIGENCIA
FROM TB_SOLICITACAO sa
WHERE sa.ID_SOLICITACAO = 1077)-- s.ID_SOLICITACAO)
CONNECT BY
PRIOR oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA) oc2
INNER JOIN TB_PERMISSAO pe2_ ON pe2_.ID_ORGAO_INTELIGENCIA = oc2.ID_ORGAO_INTELIGENCIA
INNER JOIN TB_USUARIO u_ ON u_.ID_USUARIO = pe2_.ID_USUARIO
WHERE pe2_.ID_STATUS_PERMISSAO = 7
AND pe2_.ID_ATRIBUICAO IN :atribuicoes
ORDER BY oc2.ord) oc3
The result:
That important value from each row is the S.ID_SOLICITACAO, because based on that value that the subquery will be started.
I need to be able to filter the results by oc3.ID_ORGAO_INTELIGENCIA where it brings me all the rows before that number.
So, If I filter by 430, only the row with 311 will return.
If I filter by 329, it will bring me the: 311 and 430.
Is there a way to achieve this result?

One option might be to use your current query as a CTE, and then filter data it returns. Something like this:
with ycq as
-- your current query
(select ...
from ...
)
select *
from ycq a
where a.ord < (select b.ord
from ycq b
where b.id_orgao_inteligencia = :par_id_orgao_inteligencia
);

Related

subquerying in WHERE/Joining 3 tables, 2 for records and one for number, returns no result/fails - MSAccess

My query does return any records. Depending on how I write it, it returns no records or all records, although I don't have the code that just returned everything.
I need to pull data from two sources with actual records, and a third table which has project-wide information not specific to any records. I need to filter out records which are greater than the Miles_Budgeted variable.
This returns no records, although if I replaces param.Miles_Budgeted with a numeric value e.g. 1000, it filters to the desired records.
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.cpminrmd,
a.RunTotMiles,
param.Miles_Budgeted
FROM
(SELECT (p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Miles_Budgeted FROM Tbl_Project_Parameters as p) AS param,
qry_par_l2_by_cpermi AS a
INNER JOIN
qry_l2 AS b
ON a.l1l2 = b.l1l2
WHERE
((a.RunTotMiles) <=
(Param.Miles_Budgeted
)
)
ORDER BY
a.sort_id;
This variant of the query does not run (Syntax Error in FROM Clause)
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.cpminrmd,
a.runtotmiles,
param.miles_budgeted
FROM (
(
SELECT (p.budget_cost_targ / p.project_cost_per_mi) AS miles_budgeted
FROM tbl_project_parameters AS p ) AS param
INNER JOIN qry_par_l2_by_cpermi AS a )
INNER JOIN qry_l2 AS b
ON a.l1l2 = b.l1l2
AND (
a.runtotmiles) <= ( param.miles_budgeted )
ORDER BY a.sort_id;
This also returns no records:
SELECT
a.sort_id,
a.l1l2,
a.rtot_pct_oftot_miles,
b.sumofeq,
b.c_per_mile,
b.sumofo_total,
a.RunTotMiles,
a.cpminrmd
FROM
qry_par_l2_by_cmipermi AS a
INNER JOIN
qry_l2 AS b
ON a.l1l2 = b.l1l2
WHERE
(
((a.RunTotMiles) <=
(
SELECT
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p
)
)
)
ORDER BY
a.sort_id;
Again, if
SELECT
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p
is replaces with a numeric value, the query returns the correct records. I have tried surrounding the subq or field with val() or Format(,"Standard") but this does not see to fix the issue; a separate query with just the relevant code returns the correct Budgeted_Miles as 1000 as it should.
Any thoughts appreciated.
Have you tried limiting that subquery to return only one record? I know some versions of SQL don't like when you try comparing the results of a SELECT to a single value.
I believe the syntax for MS Access would use "TOP":
SELECT TOP 1
(p.Budget_Cost_Targ / p.Project_Cost_Per_Mi) AS Budgeted_Miles
FROM
Tbl_Project_Parameters AS p

Calculate MAX for every row in SQL

I have this tables:
Docenza(id, id_facolta, ..., orelez)
Facolta(id, ...)
and I want to obtain, for every facolta, only the id of Docenza who has done the maximum number of orelez and the number of orelez:
id_docenzaP facolta1 max(orelez)
id_docenzaQ facolta2 max(orelez)
...
id_docenzaZ facoltaN max(orelez)
how can I do this? This is what i do:
SELECT DISTINCT ... F.nome, SUM(orelez) AS oreTotali
FROM Docenza D
JOIN Facolta F ON F.id = D.id_facolta
GROUP BY F.nome
I obtain somethings like:
docenzaP facolta1 maxValueForidP
docenzaQ facolta1 maxValueForidQ
...
docenzaR facolta2 maxValueForidR
docenzaS facolta2 maxValueForidS
...
docenzaZ facoltaN maxValueForFacoltaN
How can I take only the max value for every facolta?
Presumably, you just want:
SELECT F.nome, sum(orelez) AS oreTotali
FROM Docenza D JOIN
Facolta F
ON F.id = D.id_facolta
GROUP BY F.nome;
I'm not sure what the SELECT DISTINCT is supposed to be doing. It is almost never used with GROUP BY. The . . . suggests that you are selecting additional columns, which are not needed for the results you want.
This is untested, and since you didn't provide sample data with expected results I can't be sure it's really what you need.
It's a bit ugly and I'm sure there is some clever correlated sub query approach, but I've never been good with those.
SELECT st.focolta,
s_orelez,
TMP3.id_docenza
FROM some_table AS st
INNER
JOIN (SELECT *
FROM (SELECT focolta,
s_orelez,
id_docenza,
ROW_NUMBER() OVER -- Get the ranking of the orelez sum by focolta.
( PARTITION BY focolta
ORDER BY s_orelez DESC
) rn_orelez
FROM (SELECT focolta,
id_docenza,
SUM(orelez) OVER -- Sum the orelez by focolta
( PARTITION BY focolta
) AS s_orelez
FROM some_table
) TMP
) TMP2
WHERE = TMP2.rn_orelez = 1 -- Limit to the highest rank value
) TMP3
ON some_table.focolta = TMP3.focolta; -- Join to focolta to the id associated with the hightest value.

Select all rows with max date for each ID

I have the following query returning the data as shown below. But I need to exclude the rows with MODIFIEDDATETIME shown in red as they have a lower time stamp by COMMITRECID. As depicted in the data, there may be multiple rows with the max time stamp by COMMITRECID.
SELECT REQCOMMIT.COMMITSTATUS, NOTEHISTORY.NOTE, NOTEHISTORY.MODIFIEDDATETIME, NOTEHISTORY.COMMITRECID
FROM REQCOMMIT INNER JOIN NOTEHISTORY ON REQCOMMIT.RECID = NOTEHISTORY.COMMITRECID
WHERE REQCOMMIT.PORECID = 1234
Here is the result of the above query
The desired result is only 8 rows with 5 in Green and 3 in Black (6 in Red should get eliminated).
Thank you very much for your help :)
Use RANK:
WITH CTE AS
(
SELECT R.COMMITSTATUS,
N.NOTE,
N.MODIFIEDDATETIME,
N.COMMITRECID,
RN = RANK() OVER(PARTITION BY N.COMMITRECID ORDER BY N.MODIFIEDDATETIME)
FROM REQCOMMIT R
INNER JOIN NOTEHISTORY N
ON R.RECID = N.COMMITRECID
WHERE R.PORECID = 1234
)
SELECT *
FROM CTE
WHERE RN = 1;
As an aside, please try to use tabla aliases instead of the whole table name in your queries.
*Disclaimer: You said that you wanted the max date, but the selected values in your post were those with the min date, so I used that criteria in my answer
This method just limits your history table to those with the MINdate as you described.
SELECT
REQCOMMIT.COMMITSTATUS,
NOTEHISTORY.NOTE,
NOTEHISTORY.MODIFIEDDATETIME,
NOTEHISTORY.COMMITRECID
FROM REQCOMMIT
INNER JOIN NOTEHISTORY ON REQCOMMIT.RECID = NOTEHISTORY.COMMITRECID
INNER JOIN (SELECT COMMITRECID, MIN(MODIFIEDDATETIME) DT FROM NOTEHISTORY GROUP BY COMMITRECID) a on a.COMMITRECID = NOTEHISTORY.COMMITRECID and a.DT = NOTEHISTORY.MODIFIEDDATETIME
WHERE REQCOMMIT.PORECID = 1234

SQL: Query new rows of a new date

i have table as shown here in this picture --> http://www.directupload.net/file/d/3710/lj7etq5j_png.htm
I need the correct Query to get only data_id 10.
The query should be like this: Compare the latest date rows (2014-08-08) with the earliest date rows (2014-08-06). If there is a row on 2014-08-08 which is NOT at 2014-08-06, this row should returned.
I already tried it with self-joins and Sub-Selects, but i did't get it work.
Thx for any help!
Maybe something like this is what you're looking for?
select * from Table1
where
data not in (
select data from Table1
where dataOfDate = (select min(dataofdate) from Table1)
)
and dataOfDate = (select max(dataofdate) from Table1)
The first where clause compares the data field of the returned rows to the data field in the set of oldest rows and the second where clause limits the set of rows the the newest.
Note that I'm only comparing rows based on thedatafield, so you might have to change the query if you want to includenextTableIdin the comparison.
Here is a sample SQL Fiddle.
How about something like this:
SELECT d1.* FROM Dates d1 LEFT JOIN Dates d2 ON d1.nextTableId = d2.nextTableId WHERE d1.dataofDate = '2014-08-08' AND d2.dataofDate = '2014-08-06' AND d2.data_id IS NULL;
SELECT `data_id`
FROM `my_table`
WHERE `dataOfDate` = (SELECT MAX(`dataOfDate`) FROM `my_table`)
AND `nextTableId` NOT IN (
SELECT `nextTableId` FROM `my_table` WHERE `dataOfDate` = (SELECT MIN(`dataOfDate`) FROM `my_table`)
)
select all rows with max date
that don't have values amongst rows with min date
edit ops, too late

Unexpected SQL Results - Need advice

The top query is just showing the results I am expecting before I join another table to perform some calculations in Crystal Reports.
select
DriveID, FromDateTime, accountid, LocationID, StatusID
from
DriveMaster
where
AccountID = '3813'
order by
FromDateTime desc;
Results:
Query Results
This second query is where I apply a couple of filters (specifying accountid, locationid, statusid, and which occur before a specific date).
select
dm.driveid, dm.fromdatetime, dm.accountid, dpact.ProcedureProjection,
dpact.ProceduresPerformed, dpact.ProductProjection, dpact.ProductsCollected,
dm.locationid
from
rpt_drivemaster dm
inner join
driveprojectionandcollectedtotals dpact on dm.driveid = dpact.driveid
where
dm.statusid = 2
and dm.accountid = '3813'
and dm.locationid = '4018'
and dm.fromdatetime < '20140602'
and dm.fromdatetime in (select top 3 dm2.fromdatetime
from rpt_drivemaster dm2
where dm2.accountid = '3813'
and dm2.statusid = 2
order by dm2.fromdatetime desc);
The only results I am getting however are:
Query Results 2
Based on the earlier query, I was expecting results for DriveIDs of:
1. 314933
2. 205250
3. 184779
Any suggestions on what I am missing here?
The problem is in your subquery that is passed in the IN – it is returning three rows with DriverID 548002,314933 and 205250. The first row has LocationID = 31036 so it doesn't go in the result set because in your main query there is a condition dm.locationid='4018'.You should pass this condition in the subquery too, to get the desired result :
select top 3 dm2.fromdatetime
from rpt_drivemaster dm2
where dm2.accountid='3813'
and dm2.statusid=2
and dm2.LocationID = '4018'
order by dm2.fromdatetime desc