How to insert one column from a table into another based on a join/where clause - sql

I have two tables, temp_am and amphibian. The relationship between the two tables comes from the lake_id and the survey_date column in both tables. Both tables have 24,109 entries.
temp_am
id
lake_id
survey_date
1
10,001
7/25/2001
5
10,005
7/27/2001
6
10,006
7/29/2001
etc...
amphibain
id
lake_id
survey_date
amhibian_survey_id
1
10,002
7/25/2001
2
10,005
7/27/2001
etc...
I want to input the temp_am.id into the amphibian.amphibian_survey_id when both lake_ids and survey dates equal each other.
I have tried this sql query but it never worked. I canceled the query after 600 seconds as I figured a 29,000 observation table should not take that long. Please let me know if you see any issues in my query statement.
update amphibian
set amphibian_survey_id = tm.id
from amphibian a
inner join temp_am tm
on a.lake_id = tm.lake_id
and a.survey_date = tm.survey_date
This query worked in microsoft access but not on DBeaver
UPDATE amphibian
inner JOIN amphibian_survey_meta_data md ON
(amphibian.survey_date = md.survey_date) AND (amphibian.lake_id = md.lake_id) SET amphibian.amphibian_survey_id = [md.id];

Postgres does not require repeating the table name for an update join. In this case even the join is not necessary just set <column> = ( select ... ) is sufficient. See demo here.
update amphibain a
set amhibian_survey_id =
( select tm.id
from temp_am tm
where (tm.lake_id, tm.survey_date) =
(a.lake_id, a.survey_date)
) ;

Related

Sub-query works but would a join or other alternative be better?

I am trying to select rows from one table where the id referenced in those rows matches the unique id from another table that relates to it like so:
SELECT *
FROM booklet_tickets
WHERE bookletId = (SELECT id
FROM booklets
WHERE bookletNum = 2000
AND seasonId = 9
AND bookletTypeId = 3)
With the bookletNum/seasonId/bookletTypeId being filled in by a user form and inserted into the query.
This works and returns what I want but seems messy. Is a join better to use in this type of scenario?
If there is even a possibility for your subquery to return multiple value you should use in instead:
SELECT *
FROM booklet_tickets
WHERE bookletId in (SELECT id
FROM booklets
WHERE bookletNum = 2000
AND seasonId = 9
AND bookletTypeId = 3)
But I would prefer exists over in :
SELECT *
FROM booklet_tickets bt
WHERE EXISTS (SELECT 1
FROM booklets b
WHERE bookletNum = 2000
AND seasonId = 9
AND bookletTypeId = 3
AND b.id = bt.bookletId)
It is not possible to give a "Yes it's better" or "no it's not" answer for this type of scenario.
My personal rule of thumb if number of rows in a table is less than 1 million, I do not care optimising "SELECT WHERE IN" types of queries as SQL Server Query Optimizer is smart enough to pick an appropriate plan for the query.
In reality however you often need more values from a joined table in the final resultset so a JOIN with a filter WHERE clause might make more sense, such as:
SELECT BT.*, B.SeasonId
FROM booklet_tickes BT
INNER JOIN booklets B ON BT.bookletId = B.id
WHERE B.bookletNum = 2000
AND B.seasonId = 9
AND B.bookletTypeId = 3
To me it comes down to a question of style rather than anything else, write your code so that it'll be easier for you to understand it months later. So pick a certain style and then stick to it :)
The question however is old as the time itself :)
SQL JOIN vs IN performance?

Select information from different table SQL

SELECT Boeking.reisnummer, (aantal_volwassenen + aantal_kinderen) AS totaal_reizigers
FROM Boeking
WHERE Boeking.reisnummer = Reis.Reisnummer
AND Reis.Reisnummer = Reis.Bestemmingscode;
Table 1 (Boeking) has aantal_volwassen and aantal_kinderen, and Reisnummer.
Table 2 (Reis) has Reisnummer and Bestemmingscode.
I have to show the total of aantal_volwassenen and aantal_kinderen. But i also have to show Reis.bestemmingscode which comes from a different table. Currently i have to enter a parameter, how can i solve this?
You need to specify all the tables in the FROM part of your query. The tables should then be joined (JOIN) to get the data you need.
SELECT Boeking.reisnummer
,(aantal_volwassenen + aantal_kinderen) AS totaal_reizigers
,Reis.Bestemmingscode
FROM Boeking INNER JOIN Reis
ON Boeking.reisnummer = Reis.Reisnummer

Update 1 field in a table from another field in a different table (OS400, not a 1 to 1 relationship)

Im trying to update a field in a table from another field in a different table.
The table being updated will have multiple records that need updating from 1 match in the other table.
Example, i have a 1 million row sales history file. Those million records have aproximately 40,000 different sku codes, each row has a date and time stamp. Each sku will have multiple records in there.
I added a new field called MATCOST (material cost).
I have a second table containing SKU and the MATCOST.
So i want to stamp every line in table 1 with the corresponding SKU's MATCOST in table2. I cannot seem to achieve this when its not a 1 to 1 relationship.
This is what i have tried:
update
aulsprx3/cogtest2
set
matcost = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM )
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
But that results in the SQL error: Column qualifier or table COSKITSCOG undefined and highlighting the q in the last reference to queryfiles/coskitscog.Item
Any idea's ?
Kindest Regards
Adam
Update: This is what my tables look like in principle. 1 Table contains the sales data, the other contains the MATCOSTS for the items that were sold. I need to update the Sales Data table (COGTEST2) with the data from the COSKITCOG table. I cannot use a coalesce statement because its not a 1 to 1 relationship, most select functions i use result in the error of multiple selects. The only matching field is Item=Item99
I cant find a way of matching multiple's. In the example we would have to use 3 SQL statements and just specify the item code. But in live i have about 40,000 item codes and over a million sales data records to update. If SQL wont do it, i suppose i'd have to try write it in an RPG program but thats way beyond me for the moment.
Thanks for any help you can provide.
Ok this is the final SQL statement that worked. (there were actually 3 values to update)
UPDATE atst2f2/SAP20 ct
SET VAL520 = (SELECT cs.MATCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL620 = (SELECT cs.LABCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL720 = (SELECT cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
This more compact way to do the same thing should be more efficient, eh?
UPDATE atst2f2/SAP20 ct
SET (VAL520, VAL620, VAL720) =
(SELECT cs.MATCOST, cs.LABCOST, cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20)
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
Qualify the columns with correlation names.
UPDATE AULSPRX3/COGTEST2 A
SET A.matcost = (SELECT matcost
FROM QUERYFILES/COSKITSCOG B
WHERE A.item99 = B.item)
WHERE EXISTS(SELECT *
FROM QUERYFILES/COSKITSCOG C
WHERE A.item99 = C.item)
From UPDATE, I'd suggest:
update
aulsprx3/cogtest2
set
(matcost) = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM)
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
Note the braces around matcost.

SQL - Query Select Joins through multiple tables

Here is the situation:
I search for Persons with ID (empr.empr_cb)
that has bill(s) to pay (transactions.montant)
this refers to transactions.compte_id
which is identical to comptes.id_compte
this refers to comptes.proprio.id
which is identical to empr.id_empr
that would give us the Person ID (empr.empr_cb)
I tried this, but I don't know what joins to set (cross Join?):
SELECT `empr`.`empr_cb`,`transactions`.`montant`
FROM `empr`,`comptes`,`transactions`
WHERE `transactions`.`montant` > `0`
AND `transactions`.`encaissement` = `0`
AND `transactions`.compte_id` = `comptes`.`id_compte`
AND `comptes`.`proprio_id` = `id_empr`
Any ideas how to put the joins?
This query is already using implicit INNER JOINs. It can be rewritten this way:
SELECT empr.empr_cb
, transactions.montant
FROM empr
JOIN comptes ON comptes.proprio_id = empr.id_empr
JOIN transactions ON transactions.compte_id = comptes.id_compte
WHERE transactions.encaissement = 0
AND transactions.montant > 0

Why is this SQL query returning repeated records, when there not repeated in the database?

SELECT *
FROM support_systems,tickets
INNER JOIN user_access ON tickets.support_system_id = user_access.support_system_id
WHERE support_systems.account_id = #session.account_id#
AND user_access.user_access_level >= 1
AND user_access.user_id = #session.user_id#
Any clue why this query would return a record set with repeated records? The results are looking like this:
Priority ID Subject Status
high 1 First Subject open
high 1 First Subject open
low 3 Weeee open
low 3 Weeee open
medium 4 hhhhh closed
medium 4 hhhhh closed
medium 5 neat open
medium 5 neat open
Let me know if you guys need more information, thanks a lot.
You are selecting records from the table support_system but have not specified the join condition. What is the relationship between this table and the others you are interrogating?
You may want something like this
SELECT *
FROM support_systems
INNER JOIN tickets ON
support_systems.support_system_id = tickets.support_system_id
INNER JOIN user_access ON
tickets.support_system_id = user_access.support_system_id
WHERE support_systems.account_id = #session.account_id#
AND user_access.user_access_level >= 1
AND user_access.user_id = #session.user_id#
The problem is this line:
FROM support_systems,tickets
I would remove the tickets from the FROM clause and make it an inner join clause. Right now you have what's called a "cross product": http://en.wikipedia.org/wiki/Cross_product
I would have to say its probably becuase you have an explicite join and a non explicite join which isnt handled in the where which is producing a cartesian...
you have three tables...
but only two tables used in the join... you need a 2nd join... you need to include support_systems in your join somewhere.
probably like
from support_systems a left join user_access b on a.support_systems_id = b.support_systems_id
left join ticket c on c.support_systems_id = b.support_systems_id
then your where would be the same... and it would return based on the correctly joined tables.