Foreach loop on two SQL tables - sql

I have two tables which are totally independent from each other, and I need to extract information from both of them and generate a CSV.
I'm doing this query:
SELECT NOM_FLUX, TYPE_CONTENU, DATE_DEPOT_GED
FROM FLUX_GED
WHERE TYPE_CONTENU = 'TEMPO_COURRIER_FSS'
AND NOM_FLUX NOT LIKE 'PCC%'
With this result:
Then I'm doing a query from this result with the ID
Like This (on the first result)
SELECT ID, URL_RELATIVE, TYPE_CONTENU, NOM_ELEMENT
FROM ELEMENT_GED
WHERE ID IN (
SELECT ID_ELEMENT
FROM SUIVI_GED
WHERE ID_FLUX IN (18682403)
)
With this result:
And here is the information from the SUIVI_GED table:
First I would like to do like a PowerShell foreach loop on every ID of my first query and then export the result of both query in a common csv.
I would like a result like that for my csv:
NOM_FLUX;URL_RELATIVE;TYPE_CONTENU;NOM_ELEMENT
infoNomFlux;infoURL;infoType;infoNOM

You seem to want join. A rather literal translation of your queries would be:
select
f.nom_flux,
f.type_contenu as type_contenu_flux,
f.date_depot_ged ,
e.id,
e.url_relative,
e.type_contenu as type_contenu_element,
e.nom_element
from flux_ged f
inner join element_ged e
on exists (select 1 from suivi_ged s where s.id_flux = f.id and e.id = s.id)
where
f.type_contenu = 'TEMPO_COURRIER_FSS'
and f.nom_flux not like 'PCC%'
Depending on your actual design, you might be able to flatten the exists condition as another join:
select
f.nom_flux,
f.type_contenu as type_contenu_flux,
f.date_depot_ged ,
e.id,
e.url_relative,
e.type_contenu as type_contenu_element,
e.nom_element
from flux_ged f
inner join suivi_ged s on s.id_flux = f.id
inner join element_ged e on e.id = s.id
where
f.type_contenu = 'TEMPO_COURRIER_FSS'
and f.nom_flux not like 'PCC%'

Related

Can you help me to write recursive query for two tables?

I need to write recursive query for finding all child nodes in this tables.
For example i need find all child ExecutorTasks for ParentManagerTaskId = 6
ManagerTasks
{
Id,
ParentExecutorTaskId
}
ExecutorTasks
{
Id,
ParentManagerTaskId
}
;WITH query AS
(
SELECT et.Id,et.ParentManagerTaskId,mt.ParentExecutorTaskId
FROM [Planning.ExecutorTasks] et
left outer join [Planning.ManagerTasks] mt on et.ParentManagerTaskId=mt.Id
WHERE mt.Id = 6
UNION ALL
SELECT q.Id, q.ParentManagerTaskId,et.Id
FROM [Planning.ExecutorTasks] et
JOIN query q ON et.Id = q.Id
)
SELECT *
FROM query
Your model is a little misleading since you have 2 tables that are related against each other and you only want to display records from one. This means you have to do 2 joins on the recursive part to get the children of the related entity.
Try with the following:
;WITH Recursion AS
(
-- Anchor
SELECT
ExecutorTaskId = E.Id,
RecursionLevel = 0
FROM
[Planning.ExecutorTasks] AS E
WHERE
E.ParentManagerTaskId = 6
UNION ALL
-- Further childs
SELECT
ExecutorTaskId = E.Id,
RecursionLevel = R.RecursionLevel + 1
FROM
Recursion AS R
INNER JOIN [Planning.ManagerTasks] AS M ON R.ExecutorTaskId = M.ParentExecutorTaskId
INNER JOIN [Planning.ExecutorTasks] AS E ON M.Id = E.ParentManagerTaskId
)
SELECT
R.RecursionLevel,
R.ExecutorTaskId
FROM
Recursion AS R
ORDER BY
R.RecursionLevel,
R.ExecutorTaskId
I can't test if you don't supply example values, expected outcome and table's DDL.

SQL query to retrieve last record from a linked table [duplicate]

This question already has answers here:
SQL join: selecting the last records in a one-to-many relationship
(13 answers)
Closed 6 years ago.
I wrote a query to compare 2 columns in different tables (TRELAY VS TUSERDEF8). The query works great, except that it retrieves the top record in the TUSERDEF8 table which has a many to one relationship to the TRELAY table.
The tables are linked by TRELAY.ID = TUSERDEF8.N01. I would like to retrieve the latest record from TUSERDEF8 and compare that record with the TRELAY record. I plan to use the max value of the index column (TUSERDEF8.ID) to determine the latest record.
I am using SQL Server.
My code is below, but I'm not sure how to change the query to retrieve the last TUSERDEF8 record. Any help is appreciated.
SELECT
TRELAY.ID, TRELAY.S15,
TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06
FROM
TRELAY
INNER JOIN
TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01
WHERE
LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1)
AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND
TUSERDEF8.S04 LIKE '%N/A%' AND
TUSERDEF8.S06 LIKE '%EACMS%')
Making the assumption that your IDs are int(s) then the below might work?
SELECT TOP 1 TRELAY.ID, TRELAY.S15, TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06
FROM TRELAY INNER JOIN TUSERDEF8
ON TRELAY.ID = TUSERDEF8.N01
WHERE LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1)
AND NOT (
TRELAY.S15 LIKE '%MEDIUM%'
AND TUSERDEF8.S04 LIKE '%N/A%'
AND TUSERDEF8.S06 LIKE '%EACMS%'
)
ORDER BY TUSERDEF8.ID DESC
HTH
Dave
You could do this:
With cteLastRecord As
(
Select S04, N01, S06,
Row_Number() Over (Partition By N01, Order By ID Desc) SortOrder
From TUSERDEF8
)
SELECT
TRELAY.ID, TRELAY.S15,
TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06
FROM
TRELAY
INNER JOIN
(Select S04, N01, S06 From cteLastRecord Where SortOrder = 1) TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01
WHERE
LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1)
AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND
TUSERDEF8.S04 LIKE '%N/A%' AND
TUSERDEF8.S06 LIKE '%EACMS%')
I believe that your expected output is still a little ambiguous.
It sounds to me like you want only the record from the output where TUSERDEF8.ID is at its max. If that's correct, then try this:
SELECT TRELAY.ID, TRELAY.S15, TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06
FROM TRELAY
INNER JOIN TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01
WHERE LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1)
AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND
TUSERDEF8.S04 LIKE '%N/A%' AND
TUSERDEF8.S06 LIKE '%EACMS%')
AND TUSERDEF8.ID IN (SELECT MAX(TUSERDEF8.ID) FROM TUSERDEF8)
EDIT: After reviewing your recent comments, it would seem something like this would be more suitable:
SELECT
, C.ID
, C.S15,
, D.S04
, D.N01
, D.S06
FROM (
SELECT A.ID, A.S15, MAX(B.ID) AS MaxID
FROM TRELAY AS A
INNER JOIN TUSERDEF8 AS B ON A.ID = B.N01
WHERE
LEFT(A.S15, 1) <> LEFT(B.S04, 1)
AND NOT (A.S15 LIKE '%MEDIUM%' AND
B.S04 LIKE '%N/A%' AND
B.S06 LIKE '%EACMS%')
GROUP BY A.ID, A.S15
) AS C
INNER JOIN TUSERDEF8 AS D ON C.ID = D.N01 AND C.MaxID = D.ID
Using an ID column to determine which row is "last" is a bad idea
Using cryptic table names like "TUSERDEF8" (how is it different from TUSERDEF7) is a very bad idea, along with completely cryptic column names like "S04".
Using prefixes like "T" for table is a bad idea - it should already be clear that it's a table.
Now that all of that is out of the way:
SELECT
R.ID,
R.S15,
U.S04,
U.N01,
U.S06
FROM
TRELAY R
INNER JOIN TUSERDEF8 U ON U.N01 = R.ID
LEFT OUTER JOIN TUSERDEF8 U2 ON
U2.N01 = R.ID AND
U2.ID > U.ID
WHERE
U2.ID IS NULL AND -- This will only happen if the LEFT OUTER JOIN above found no match, meaning that the row in U has the highest ID value of all matches
LEFT(R.S15, 1) <> LEFT(U.S04, 1) AND
NOT (
R.S15 LIKE '%MEDIUM%' AND
U.S04 LIKE '%N/A%' AND
U.S06 LIKE '%EACMS%'
)

SQL Join / Union

I have two statements that I want to merge into one output.
Statement One:
select name from auxiliary_variable_inquiry
where inquiry_idbr_code = '063'
Returns the following list of names:
Name
------------
Affiliates
NetBookValue
Parents
Worldbase
Statement Two:
select name, value from auxiliary_variable_value
where inquiry_idbr_code = '063'
and ru_ref = 20120000008
and period = 200912
Returns the following:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
I would like to have an output like this:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
Parents 0
Worldbase 0
So basically, if the second query only returns 2 names and values, I'd still like to display the complete set of names from the first query, with no values. If all four values were returned by both queries, then all four would be displayed.
Sorry I must add, im using Ingres SQL so im unable to use the ISNULL function.
You can do a left join. This ensures that all records from the first table will stay included. Where value is null, no child record was found, and we use coalesce to display 0 in these cases.
select i.name, COALESCE(v.Value,0) from auxiliary_variable_inquiry i
left join auxiliary_variable_value v
on v.inquiry_idbr_code = i.inquiry_idbr_code
and v.ru_ref = 20120000008
and v.period = 200912
where i.inquiry_idbr_code = '063'
I'd recommend a self-JOIN using the LEFT OUTER JOIN syntax. Include your 'extra' conditions from the second query in the JOIN condition, while the first conditions stay in the WHERE, like this:
select a.name, CASE WHEN b.Value IS NULL THEN 0 ELSE b.Value END AS Value
from
auxiliary_variable_inquiry a
LEFT JOIN
auxiliary_variable_inquiry b ON
a.name = b.name and -- replace this with your real ID-based JOIN
a.inquiry_idbr_code = b.inquiry_idbr_code AND
b.ru_ref = 20120000008 AND
b.period = 200912
where a.inquiry_idbr_code = '063'
if i got right, you should use something like:
SELECT i.NAME,
v.NAME,
v.value
FROM auxiliary_variable_inquiry i
LEFT JOIN auxiliary_variable_value v
ON i.inquiry_idbr_code = v.inquiry_idbr_code
WHERE v.ru_ref = 20120000008
AND v.period = 200912

Selecting data from two tables with sql query

I have 2 tables
Course ( ID Date Description Duration Meatier_ID Promotion_ID).
second table
Ensign( E_Id Meatier_Id Promotion_Id)
infarct i have an id based on that id i have to Select data from Ensign where id=Eng_Id then i need to select data from Course where Meatier_Id and Promotion_Id in table Course are equal to Meatier_Id and Promotion_Id to data selected in earlier query
can i do it using one S q l query thanks
Br
Sara
Your question is bit vague, But I gave it a try
--These two variables take the place for your 'Earlier Query' values
DECLARE #Meatier_ID INT = 100,
#Promotion_Id INT = 15
--The query
SELECT *
FROM Course AS C
INNER JOIN Ensign AS E ON C.ID = E.E_Id
WHERE C.Meatier_ID = #Meatier_ID
AND C.Promotion_Id = #Promotion_Id
Join the two tables together on Meater_ID and Promotion_ID. Then select those rows where Eng_Id is the id you are working with.
SELECT *
FROM Course c
INNER JOIN Ensign e
ON e.Meatier_ID = c.Meatier_ID
AND e.Promotion_ID = c.Promotion_ID
WHERE e.Eng_Id = <id value here>
EDIT:
The above should work for SQL Server. For derby, try:
SELECT *
FROM Course
INNER JOIN Ensign
ON Ensign.Meatier_ID = Course.Meatier_ID
AND Ensign.Promotion_ID = Course.Promotion_ID
WHERE Ensign.Eng_Id = <id value here>
select e.E_Id, e.Meatier_Id, e.Promotion_Id, c.ID, c.Date, c.Description, c.Duration from Ensign as e inner join course as c where e.Meatier_Id=c.Meatier_Id and e.Promotion_Id=c.Promotion_Id and e.E_Id=#Eng_Id

PostgreSQL - how to query "result IN ALL OF"?

I am new to PostgreSQL and I have a problem with the following query:
WITH relevant_einsatz AS (
SELECT einsatz.fahrzeug,einsatz.mannschaft
FROM einsatz
INNER JOIN bergefahrzeug ON einsatz.fahrzeug = bergefahrzeug.id
),
relevant_mannschaften AS (
SELECT DISTINCT relevant_einsatz.mannschaft
FROM relevant_einsatz
WHERE relevant_einsatz.fahrzeug IN (SELECT id FROM bergefahrzeug)
)
SELECT mannschaft.id,mannschaft.rufname,person.id,person.nachname
FROM mannschaft,person,relevant_mannschaften WHERE mannschaft.leiter = person.id AND relevant_mannschaften.mannschaft=mannschaft.id;
This query is working basically - but in "relevant_mannschaften" I am currently selecting each mannschaft, which has been to an relevant_einsatz with at least 1 bergefahrzeug.
Instead of this, I want to select into "relevant_mannschaften" each mannschaft, which has been to an relevant_einsatz WITH EACH from bergefahrzeug.
Does anybody know how to formulate this change?
The information you provide is rather rudimentary. But tuning into my mentalist skills, going out on a limb, I would guess this untangled version of the query does the job much faster:
SELECT m.id, m.rufname, p.id, p.nachname
FROM person p
JOIN mannschaft m ON m.leiter = p.id
JOIN (
SELECT e.mannschaft
FROM einsatz e
JOIN bergefahrzeug b ON b.id = e.fahrzeug -- may be redundant
GROUP BY e.mannschaft
HAVING count(DISTINCT e.fahrzeug)
= (SELECT count(*) FROM bergefahrzeug)
) e ON e.mannschaft = m.id
Explain:
In the subquery e I count how many DISTINCT mountain-vehicles (bergfahrzeug) have been used by a team (mannschaft) in all their deployments (einsatz): count(DISTINCT e.fahrzeug)
If that number matches the count in table bergfahrzeug: (SELECT count(*) FROM bergefahrzeug) - the team qualifies according to your description.
The rest of the query just fetches details from matching rows in mannschaft and person.
You don't need this line at all, if there are no other vehicles in play than bergfahrzeuge:
JOIN bergefahrzeug b ON b.id = e.fahrzeug
Basically, this is a special application of relational division. A lot more on the topic under this related question:
How to filter SQL results in a has-many-through relation
Do not know how to explain it, but here is an example how I solved this problem, just in case somebody has the some question one day.
WITH dfz AS (
SELECT DISTINCT fahrzeug,mannschaft FROM einsatz WHERE einsatz.fahrzeug IN (SELECT id FROM bergefahrzeug)
), abc AS (
SELECT DISTINCT mannschaft FROM dfz
), einsatzmannschaften AS (
SELECT abc.mannschaft FROM abc WHERE (SELECT sum(dfz.fahrzeug) FROM dfz WHERE dfz.mannschaft = abc.mannschaft) = (SELECT sum(bergefahrzeug.id) FROM bergefahrzeug)
)
SELECT mannschaft.id,mannschaft.rufname,person.id,person.nachname
FROM mannschaft,person,einsatzmannschaften WHERE mannschaft.leiter = person.id AND einsatzmannschaften.mannschaft=mannschaft.id;