PostgreSQL loop through subquery - sql

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

Related

How to I return a case record with latest date using SQL

I want a query that returns a record set of the shaded rows from the table above for each unique case_id by the latest data_level_assinged value. I tried something like this:
SELECT case_id, level, date_level_assigned
FROM table
SORT BY case_id, date_level_assigned DESC;
From reading it looks like I need to use an aggregate function like MAX(data_level_assinged) but am not sure how to do this.
You're almost there.
Using MAX is a good approach.
SELECT b.case_id, a.level, b.date_level_assigned FROM tablename a
JOIN
( SELECT MAX(date_level_assigned) as date_level_assigned, case_id
FROM tablename
GROUP BY case_id
) as b
ON a.case_id = b.case_id AND a.date_level_assigned = b.date_level_assigned
You can do it in this way

Query to show all ID's except the ones that have a specific instrument

So I have a table which looks like this:
What would be the best query to exclude every "stuknr" that has atleast 1 "saxofoon" in the "instrumentnaam" column?
To select all stuknr where there is not stuknr with a saxofoon:
SELECT *
FROM table
WHERE stuknr not in (
SELECT stuknr
FROM TABLE
WHERE INSTRUMENTNAAM = ‘saxofoon’)
;
SELECT STUNKR
FROM TABLE
WHERE INSTRUMENTNAAM != ‘saxofoon’;
Here != (or <>, which are equivalent, see this) means "not equal".
You can do this with a NOT IN sub-select
select distinct
YT.stunkr
from
YourTable YT
where YT.stunkr NOT IN ( select distinct stunkr
from YourTable
where InstrumentNaam = 'saxofoon' )
So the sub-select is getting all IDs that DO have saxofoon and the primary select/from is getting where the ID is NOT in the secondary.

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

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)

Oracle: filter all rows before the ID

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
);

SQL get rows matching ALL conditions

I would like to retrieve all rows matching a set of conditions on the same column. But I would like the rows only if ALL the conditions are good, and no row if only one condition fails.
For example, taking this table:
|id|name|
---------
|1 |toto|
|2 |tata|
I would like to be able to request if "tata" && "toto" are in this table. But when asking if "tata" and "tuto" are in, I would like an empty response if one of argument is in not in the table, for example asking if "toto" && "tutu" are included in the table.
How can I do that ?
Currently, I'am doing one query per argument, which is not very efficient. I tried several solutions including a subselect or a group+having, but no one is working like I want.
thanks for your support !
cheers
This isn't the most efficient way, but this query would work.
SELECT * FROM table_name
WHERE (name = 'toto' OR name = 'tata')
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'toto') > 0
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'tata') > 0
This is a little vague. If the names are unique, you could count the matching rows that match a where clause:
where name='toto' or name='tata'
If the count is 2, then you know both matched. If name is not unique you could potentially select the first ID (select top 1 id ...) that matches each in a union and count those with an outer select.
Even if you had an arbitrary number of names to match, you could create a stored procedure or code in whatever top-level language you are using to build the select statement.
SELECT 1 AS found FROM hehe
WHERE 1 IN (SELECT 1 FROM hehe WHERE name='tata')
AND 1 IN (SELECT 1 FROM hehe WHERE name='toto')
If name is unique you can simplify to:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(*) FROM tbl WHERE name IN ('toto', 'tata')) > 1;
If it isn't:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND EXISTS (SELECT * FROM tbl WHERE name = 'toto')
AND EXISTS (SELECT * FROM tbl WHERE name = 'tata');
Or, in PostgreSQL, MySQL and possibly others:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(DISTINCT name) FROM tbl WHERE name IN ('toto', 'tata')) > 1;