Selecting data from two tables with sql query - sql

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

Related

Foreach loop on two SQL tables

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%'

Need Combined SQL Query to Update 2 Tables

I am having 2 tables. Table1 and Table2. I need to update these 2 tables based on some conditions.
The SQL select query from Table1 will return multiple records, let's
name it as SQLQuery1
From SQLQuery1 results returned I need to loop through each record and
execute another SQL query from Table2 which will return only 1
record, let's name it as SQLQuery2
Update Table1 and Table2 with the results returned from SQLQuery2.
Is there is a single query to combine the above operations?
If you need more information please let me know
UPDATE:
Following are the Sample Queries used,
SELECT E.Id,E.Name
from Employee E
where E.transdate > '2019-01-201 00:00:01' -- Multiple Results(SQLQuery1)
SELECT top 1 ED.Id,ED.balance
FROM EmployeeDetails ED
where ED.Name= #Name -- Single Results((SQLQuery2)
UPDATE Employee set IsProcessed=true
where Id=#Id
UPDATE EmployeeDetails set IsProcessed=true
where Id=#Id
I would use an UPDATE with an INNER JOIN. I have no idea if it's best practice at this point in time or whether there is a better way to do this but it works for the example I have created in dbfiddle.
Something like this:
UPDATE E
SET IsProcessed = 1
FROM Employee E
INNER JOIN EmployeeDetails ED ON E.Id = ED.Id
WHERE E.transdate >= '2019-01-20 00:00:01' AND ED.name = 'Martin'
UPDATE ED
SET IsProcessed = 1
FROM EmployeeDetails ED
INNER JOIN Employee E ON E.Id = ED.Id
WHERE E.transdate >= '2019-01-20 00:00:01' AND ED.name = 'Martin'
I used >= because I just set all 3 created records to the datetime you have and forgot that looking for a datetime greater than that would provide me with nothing. I also used a hard-coded name Martin instead of using a variable.
Here is my link to the dbfiddle I created in which I created Employee and EmployeeDetails, filled them with test data and then proceeded to identify the correct records using the date, time and name joined by their ID values:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4492b27a9790f34b0bff0996e7fb6d36
Use INNER JOIN :
update e
set e.IsProcessed = 1 -- assuming BIT type
from employee e inner join
EmployeeDetails ed
on ed.name = e.name and ed.id = e.id
where e.transdate > '2019-01-201 00:00:01';
update ed
set ed.IsProcessed = 1 -- assuming BIT type
from EmployeeDetails ed inner join
Employee e
on ed.name = e.name and ed.id = e.id and
where e.transdate > '2019-01-201 00:00:01';
I wouldn't do it like this.
You can use outer apply to get rid of the cursor:
SELECT *
FROM T_Query1
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = T_Query1.id
) AS tQuery2
Then you can do an update like this:
UPDATE A
SET some_value = tQuery2.some_new_value
FROM T_Query1 AS A
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = A.id
) AS tQuery2
Besides that, you cannot update 2 tables with one update statement, AFAIK.
Your best bet would be
;WITH CTE AS
(
SELECT T_Query1.field1, T_Query2.field2, T_Query2.newField1
FROM T_Query1
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = T_Query1.id
) AS tQuery2
)
-- SELECT * FROM CTE
UPDATE CTE SET field1 = newField1, field2 = newField1
but I don't think CTE updating can handle outer-apply.

Oracle: Nested joins/sub-queries: Odd column names and one unexplained error

The following query works fine. It is a series of nested joins to give me a kind of master table:
SELECT *
FROM proj_trainer k
JOIN
(
SELECT *
FROM proj_breeder i
JOIN
(
SELECT *
FROM proj_jockey g
JOIN
(
SELECT *
FROM proj_horses e
JOIN
(
SELECT *
FROM proj_results c
JOIN
(
SELECT *
FROM proj_race_details a
JOIN proj_meet b
ON a.meet_id = b.meet_id
) d
ON c.race_id = d.race_id
) f
ON e.horse_id = f.horse_id
) h
ON g.jockey_id = h.jockey_id
)j
ON i.breeder_id = j.breeder_id
) l
ON k.trainer_id = l.trainer_id;
This works fine with one odd feature, which isn't my main problem. Some of the columns are return with strange codes such as "QCSJ_C000000001300001". Not sure why, or if this relates to my actual problem.
The real problem is that when I add just one more join sub-query I get:
ORA-00904: "N"."RACE_ID": invalid identifier
Here's the same code with the extra nested block (the one on the very outside)
SELECT *
FROM proj_entry m
JOIN
(
SELECT *
FROM proj_trainer k
JOIN
(
SELECT *
FROM proj_breeder i
JOIN
(
SELECT *
FROM proj_jockey g
JOIN
(
SELECT *
FROM proj_horses e
JOIN
(
SELECT *
FROM proj_results c
JOIN
(
SELECT *
FROM proj_race_details a
JOIN proj_meet b
ON a.meet_id = b.meet_id
) d
ON c.race_id = d.race_id
) f
ON e.horse_id = f.horse_id
) h
ON g.jockey_id = h.jockey_id
)j
ON i.breeder_id = j.breeder_id
) l
ON k.trainer_id = l.trainer_id
) n
ON n.race_id = m.race_id WHERE n.horse_id = m.horse_id;
I felt like I was well over the hill with this one and then the final line went wrong somehow, despite having virtually the same structure as all the previous blocks. I've also used the race_id and horse_id earlier in the code so they do work.
I've also tried this on the last line:
ON n.race_id = m.race_id AND n.horse_id = m.horse_id;
and a few other variations, with brackets etc....
At first I could't see anything wrong as such, but then I can't see anything terribly well with that syntax! The problem may be that "N"."RACE_ID" is ambiguous, since "N" is the alias for a query that joins many tables, perhaps more than one of which have a RACE_ID column?
Your SQL could be re-written as:
SELECT *
FROM proj_entry m
JOIN proj_trainer n ON n.race_id = m.race_id
JOIN proj_breeder l ON l.trainer_id = n.trainer_id
JOIN proj_jockey j ON j.breeder_id = l.breeder_id
JOIN proj_horses h ON h.jockey_id = j.jockey_id
JOIN proj_results f ON f.horse_id = h.horse_id
JOIN proj_race_details d ON d.race_id = f.race_id
JOIN proj_meet b ON b.meet_id = d.meet_id
WHERE n.horse_id = m.horse_id;
(But I could have made a mistake somewhere.)
That looks a lot simpler to me. It would be better still if the aliases were mnemonics for the actual table names rather than in most cases arbitrary letters of the alphabet:
SELECT *
FROM proj_entry e
JOIN proj_trainer t ON t.race_id = e.race_id
JOIN proj_breeder b ON b.trainer_id = n.trainer_id
JOIN proj_jockey j ON j.breeder_id = b.breeder_id
JOIN proj_horses h ON h.jockey_id = j.jockey_id
JOIN proj_results r ON r.horse_id = h.horse_id
JOIN proj_race_details d ON d.race_id = r.race_id
JOIN proj_meet m ON m.meet_id = d.meet_id
WHERE t.horse_id = e.horse_id;
You should then easily be able to check the joins to see that they are on the right columns. And now if you get an error like ORA-00904: "T"."RACE_ID": invalid identifier you will know for sure that it refers to table proj_trainer whereas previously "N"."RACE_ID" might be ambiguous since "N" was the alias of a query joining about half a dozen tables.
Also rather than SELECT * it might be better to specify the actual columns you want, which will avoid getting duplicates - for example:
SELECT e.race_id, t.trainer_id, t.trainer_name, ...
(I imagine the column names starting with 'QCSJ' that your query tool is generating are to cope with what would otherwise be duplicate column names in the results. What is the query tool?)

How can I join on multiple columns within the same table that contain the same type of info?

I am currently joining two tables based on Claim_Number and Customer_Number.
SELECT
A.*,
B.*,
FROM Company.dbo.Company_Master AS A
LEFT JOIN Company.dbp.Compound_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number
WHERE A.Filled_YearMonth = '201312' AND A.Compound_Ind = 'Y'
This returns exactly the data I'm looking for. The problem is that I now need to join to another table to get information based on a Product_ID. This would be easy if there was only one Product_ID in the Compound_Info table for each record. However, there are 10. So basically I need to SELECT 10 additional columns for Product_Name based on each of those Product_ID's that are being selected already. How can do that? This is what I was thinking in my head, but is not working right.
SELECT
A.*,
B.*,
PD_Info_1.Product_Name,
PD_Info_2.Product_Name,
....etc {Up to 10 Product Names}
FROM Company.dbo.Company_Master AS A
LEFT JOIN Company.dbo.Compound_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number
LEFT JOIN Company.dbo.Product_Info AS PD_Info_1 ON B.Product_ID_1 = PD_Info_1.Product_ID
LEFT JOIN Company.dbo.Product_Info AS PD_Info_2 ON B.Product_ID_2 = PD_Info_2.Product_ID
.... {Up to 10 LEFT JOIN's}
WHERE A.Filled_YearMonth = '201312' AND A.Compound_Ind = 'Y'
This query not only doesn't return the correct results, it also takes forever to run. My actual SQL is a lot longer and I've changed table names, etc but I hope that you can get the idea. If it matters, I will be creating a view based on this query.
Please advise on how to select multiple columns from the same table correctly and efficiently. Thanks!
I found put my extra stuff into CTE and add ROW_NUMBER to insure that I get only 1 row that I care about. it would look something like this. I only did for first 2 product info.
WITH PD_Info
AS ( SELECT Product_ID
,Product_Name
,Effective_Date
,ROW_NUMBER() OVER ( PARTITION BY Product_ID, Product_Name ORDER BY Effective_Date DESC ) AS RowNum
FROM Company.dbo.Product_Info)
SELECT A.*
,B.*
,PD_Info_1.Product_Name
,PD_Info_2.Product_Name
FROM Company.dbo.Company_Master AS A
LEFT JOIN Company.dbo.Compound_Info AS B
ON A.Claim_Number = B.Claim_Number
AND A.Customer_Number = B.Customer_Number
LEFT JOIN PD_Info AS PD_Info_1
ON B.Product_ID_1 = PD_Info_1.Product_ID
AND B.Fill_Date >= PD_Info_1.Effective_Date
AND PD_Info_2.RowNum = 1
LEFT JOIN PD_Info AS PD_Info_2
ON B.Product_ID_2 = PD_Info_2.Product_ID
AND B.Fill_Date >= PD_Info_2.Effective_Date
AND PD_Info_2.RowNum = 1

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;