In clause of a select but with more than one value to look for - sql

I have a set of results that I query with connect by prior, now I need to check in the where clause of a query if ONE of those results is IN some other set of values(a select * from another table). I'm trying to use 'IN' but I think that that only works when I have one unique value to check for, and not a group of values.
SELECT COUNT('X')
INTO V_COUNT
FROM SIC_NEA_CATFRU
WHERE (SELECT cod_nivel_estr_art
FROM niveles_estr_art
CONNECT BY PRIOR cod_nivel_estr_art_P = cod_nivel_estr_art
START WITH cod_nivel_estr_art = V_COD_NIVEL_eSTR_ART) IN ( SELECT COD_NIVEL_eSTR_ART FROM SIC_NEA_CATFRU);

Would the intersect set operator do? Something like this: first query is your hierarchical query, while the second returns values from the sic_nea_catfru table. If there are any matches, you'll know how many:
SELECT COUNT (*)
INTO v_count
FROM ( SELECT cod_nivel_estr_art
FROM niveles_estr_art
CONNECT BY PRIOR cod_nivel_estr_art_p = cod_nivel_estr_art
START WITH cod_nivel_estr_art = v_cod_nivel_estr_art
INTERSECT
SELECT cod_nivel_estr_art FROM sic_nea_catfru)

Related

Automatic Fetch one record

I am execute below query. there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record.
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between '01-Oct-2019' and '14-Oct-2019';
But dont use Group BY function.
there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record
That's not how aggregate queries work.
An aggregate query with no GROUP BY returns one row. The result is the aggregation applied to the filtered rows. Because you had no rows which matched your criteria the aggregated value is NULL. If you had used a COUNT() function instead you would have got zero.
So, if you really want an empty result set (zero rows) when there's no matching data you can use this trick:
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between date '2019-10-01' and date '2019-10-14'
having count(*) > 0
;
Incidentally, you should get into the habit of using date literals instead of relying on implicit data conversion.
Quick demonstration about what you need
with w0 as
(
select 1 x from dual union
select 2 from dual
), w1 as
(
select * from w0 where 1=2
)
select c1 from (
select sum(x) c1 from w1
)
where c1 is not null
Click here for demo
Try this query
select sum(null) c1 from dual where 1=2
No data due to 1=2 but one row result

How to Integrate these two Queries into one Query?

Can someone please tell me how can I merge these two queries into one Query?
I have already tried this code but the problem here that it does not update the Adserver table.
with first as (
select *, c_date = Current_date() from FRIDAY.Adserver where C_date IS NULL
),
second as (
select * from FRIDAY.Adserver JOIN FRIDAY.Matching_Table
ON Adserver.Placement_ExtID = Matching_Table.string_field_0
),
Tird As(
Select *, CONCAT(Cast(Date as String),"-",Second.string_field_0) AS New_IDS from Second
) Select * from Tird
First I need to update the Adserver Table with the current Date:
QUERY 1:
UPDATE FRIDAY.Adserver SET C_date() = CURRENT_Date() Where C_date IS NULL ;
And then I would only pick the data with the current date:
QUERY 2:
With First As(
select * from FRIDAY.Adserver where C_date = Current_date()
),
Second As(
select * from First JOIN FRIDAY.Matching_Table1
ON First.Placement_ExtID = Matching_Table1.string_field_1 OR First.Placement_ExtID = Matching_Table1.string_field_0
),
Tird As(
Select *, CONCAT(Cast(Date as String),"-",Second.string_field_0) AS New_IDS from Second ) Select * from Tird
Is there anyway to combine the above Query 1 and Query 2?
That's not possible.
A query can either change data (INSERT, UPDATE, DELETE) or return data (SELECT). To do both "at the same time" code is necessary. But this depends on the used DB server.
For example, you could create a function that first executes the UPDATE statement and then returns the data from the SELECT statement. But as I said, if and how this is possible depends on the DB system.

"FOR UPDATE is not allowed with aggregate functions" in PostgreSQL

Here is pseudo code for what I'm trying to do:
rate_count = SELECT COUNT(id) FROM job WHERE last_processed_at >= ?
current_limit = rate_limit - rate_count
if current_limit > 0
UPDATE job SET state='processing'
WHERE id IN(
SELECT id FROM job
WHERE state='pending'
LIMIT :current_limit
)
I have it working except for concurrency issues. When run from multiple sessions at the same time, both sessions SELECT and therefore update the same stuff :(
I'm able to get the 2nd query atomic by adding FOR UPDATE in it's SELECT subquery. But I can't add FOR UPDATE to the first query because FOR UPDATE isn't allowed with aggregate functions
How can I make this piece an atomic transaction?
You can do FOR UPDATE within a subquery:
rate_count := COUNT(id)
FROM (
SELECT id FROM job
WHERE last_processed_at >= ? FOR UPDATE
) a;
You can also do this whole thing in a single query:
UPDATE job SET state='processing'
WHERE id IN (
SELECT id FROM job
WHERE state='pending'
LIMIT (SELECT GREATEST(0, rate_limit - COUNT(id))
FROM (SELECT id FROM job
WHERE last_processed_at >= ? FOR UPDATE) a
)
)
I got the same error below:
ERROR: FOR UPDATE is not allowed with aggregate functions
Because I use count() and FOR UPDATE as shown below:
SELECT count(*) FROM person FOR UPDATE;
So, I changed the query above to one of 2 queries below:
SELECT count(*) FROM (SELECT * FROM person FOR UPDATE) AS result;
WITH result AS (SELECT * FROM person FOR UPDATE) SELECT count(*) FROM result;
Then, I could use count() and FOR UPDATE together:
count
-------
7
(1 row)

PostgreSQL loop through subquery

I'd like to loop through the results of a select subquery and use them yo fetch data off of another table:
SELECT alias, profile_picture
FROM public.profile
where user_id = (
SELECT friend_user_id
FROM public.friends
where user_id = 1059948007363671)::text
obviously this query returns:
ERROR: more than one row returned by a subquery used as an expression
What would be the best way to loop through the subquery results and assign it to a temporary variable that pubic.profile could use to fetch the respective profile info?
Use in instead of =:
WHERE user_id IN
(
SELECT friend_user_id::text
FROM public.friends
WHERE user_id = 1059948007363671
)
SELECT alias, profile_picture
FROM public.profile
JOIN public.friends
ON profile.user_id=friends.friend_user_id
WHERE friends.user_id = 1059948007363671

Determine active rows from multiple tables and place in a Variable Table

I have to determine how many rows are active from each Table. Then return the answers in one query AND put the results in a Table Variable.
a. Path
b. Course
c. Section
d. Event
I was able to determine the active rows with the following query:
SELECT * FROM [dbo].[ADF_Path]
WHERE PathActive is NULL
SELECT * FROM [dbo].[ADF_Course]
WHERE CourseActive = '1'OR
CourseActive = 'y'
SELECT * FROM [dbo].[ADF_Event]
WHERE EventActive = 'y'
Is it POSSIBLE to join these tables in order to arrive at the same conclusion
OR
How do I determine the active rows in 1 query?
Placing the query in a Variable Table is not a problem. I just need to know
how to formulate the query. (See Tables below)
Thank You
do you want something like?:
SELECT count(*) as cnt FROM [dbo].[ADF_Path] WHERE PathActive is NULL
union all
SELECT count(*) FROM [dbo].[ADF_Course] WHERE CourseActive = '1' OR CourseActive = 'y'
union all
SELECT count(*) FROM [dbo].[ADF_Event] WHERE EventActive = 'y'
you can also add column to distinguish between different counts, or summarize them like:
select sum(cnt) from ( <union query from above> ) as t