How to update the PK of every record - sql

I have two tables that are exactly the same, except for one column. Both tables have the same amount of records and the same amount of columns, and all of the data is the same.
Table A:
+--------------------------------------+--------+--------+---------+
| GUID | Animal | Person | Vehicle |
+--------------------------------------+--------+--------+---------+
| 1D001609-7071-4DBB-9E65-0000B3EEF751 | cat | matt | car |
| 90260783-E3C3-4A9B-BEA0-000388EA41E1 | dog | rich | truck |
| DD18FCFA-99BD-4FBC-AFC2-00058EF95D0A | zebra | alex | van |
+--------------------------------------+--------+--------+---------+
Table B:
+--------------------------------------+--------+--------+---------+
| GUID | Animal | Person | Vehicle |
+--------------------------------------+--------+--------+---------+
| F67A3079-8589-4304-AA3C-000688696BAA | cat | matt | car |
| C71710EC-492F-424E-805D-00068AFE4E82 | dog | rich | truck |
| 5F830142-F4CC-4580-974D-000710F1AB5F | zebra | alex | van |
+--------------------------------------+--------+--------+---------+
I need the GUIDs of table A to be updated to equal the GUIDs of Table B. Something like this will work:
update a
set a.guid=b.guid
from tablea a
join tableb b
on a.animal=b.animal
and a.person=b.person
and a.vehicle=b.vehicle
But the above solution will not work for me. I have actually approximately 50 columns and about 1 million records.
Would you have any other suggestions on how to update the GUID in table A more efficiently?

UPDATE A
SET [GUID] = (
SELECT [GUID]
FROM B
WHERE EXISTS (
SELECT A.Animal,A.Person,A.Vehicle
INTERSECT
SELECT B.Animal,B.Person,B.Vehicle
)
)

If you want the tables identical, how about this:
DROP TABLE B
SELECT *
INTO B
FROM A

Related

SQL - specific requirement to compare tables

I'm trying to merge 2 queries into 1 (cuts the number of daily queries in half): I have 2 tables, I want to do a query against 1 table, then the same query against the other table that has the same list just less entries.
Basically its a list of (let's call it for obfuscation) people and hobby. One table is ALL people & hobby, the other shorter list is people & hobby that I've met. Table 2 would all be found in table 1. Table 1 includes entries (people I have yet to meet) not found in table 2
The tables are synced up from elsewhere, what I'm looking to do is print a list of ALL people in the first column then print the hobby ONLY of people that are on both lists. That way I can see the lists merged, and track the rate at which the gap between both lists is closing. I have tried a number of SQL combinations but they either filter out the first table and match only items that are true for both (i.e. just giving me table 2) or just adding table 2 to table 1.
Example of what I'm trying to do below:
+---------+----------+--+----------+---------+--+---------+----------+
| table1 | | | table2 | | | query | |
+---------+----------+--+----------+---------+--+---------+----------+
| name | hobby | | activity | person | | name | hobby |
| bob | fishing | | fishing | bob | | bob | fishing |
| bill | vidgames | | hiking | sarah | | bill | |
| sarah | hiking | | planking | sabrina | | sarah | hiking |
| mike | cooking | | | | | mike | |
| sabrina | planking | | | | | sabrina | planking |
+---------+----------+--+----------+---------+--+---------+----------+
Normally I'd just take the few days to learn SQL a bit better however I'm stretched pretty thin at work as it is!
I should mention the table 2 is flipped and the headings are all unique (don't think this matters)!
I think you just want a left join:
select t1.name, t2.activity as hobby
from table1 t1 left join
table2 t2
on t1.name = t2.person;

Four Table Join in BigQuery

Okay, so I'm trying to link together four different tables, and its getting very difficult. I provided snippets of each table in the hopes you all could help out
Table 1: data
+--------+--------+-----------+
| charge | amount | date |
+--------+--------+-----------+
| 123 | 10000 | 2/10/2016 |
| 456 | 10000 | 1/28/2016 |
| 789 | 10000 | 3/30/2016 |
+--------+--------+-----------+
Table 2: data_metadata
+--------+------------+------------+
| charge | key | value |
+--------+------------+------------+
| 123 | identifier | trrkfll212 |
| 456 | code | test |
| 789 | ID | 123xyz |
+--------+------------+------------+
Table 3: buyer
+-----+-----------+----------+----------+
| id | date | discount | plan |
+-----+-----------+----------+----------+
| ABC | 2/13/2016 | yes | option a |
| DEF | 2/1/2016 | yes | option a |
| GHI | 1/22/2016 | no | option a |
+-----+-----------+----------+----------+
Table 4: buyer_metadata
+--------------+-----------+--------+
| id | |key| | value |
+--------------+-----------+--------+
| ABC | migration | TRUE |
| DEF | emid | foo |
| GHI | ID | 123xyz |
+--------------+-----------+--------+
Okay, so the tables data and data_metadata are obviously connected by the charge column.
The tables buyer and buyer_metadata are connected by the id column.
But I want to link all of them together. I'm pretty sure the way to accomplish this is through linking the metadata tables together through the common field in the "value" column (in this example: 123xyz).
Could anyone help?
This might look like something like that if all "link" columns are unique :
SELECT *
FROM data d
JOIN data_metadata dm ON d.charge = dm.charge
JOIN buyer_metada bm ON dm.value = bm.value
JOIN buyer b ON bm.id = b.id
If not, I think you'll have to use something like GROUP BY clause
Let's take it in two steps, first create composite tables for data and buyer. Composite table for data:
SELECT data.charge, data.amount, data.date,
data_metadata.key, data_metadata.value
FROM [data] AS data
JOIN (SELECT charge, key, value FROM [data_metadata]) AS data_metadata
ON data.charge = data_metadata.charge
And composite table for buyer:
SELECT buyer.id, buyer.date, buyer.discount, buyer.plan,
buyer_metadata.key, buyer_metadata.value
FROM [buyer] AS buyer
JOIN (SELECT key, value FROM [buyer_metadata]) AS buyer_metadata
ON buyer.id = buyer_metadata.id
And then let's join the two composite tables
SELECT composite_data.*, composite_buyer.*
FROM (
SELECT data.charge, data.amount, data.date,
data_metadata.key, data_metadata.value
FROM [data] AS data
JOIN (SELECT charge, key, value FROM [data_metadata]) AS data_metadata
ON data.charge = data_metadata.charge) AS composite_data
JOIN (
SELECT buyer.id, buyer.date, buyer.discount, buyer.plan,
buyer_metadata.key, buyer_metadata.value
FROM [buyer] AS buyer
JOIN (SELECT key, value FROM [buyer_metadata]) AS buyer_metadata
ON buyer.id = buyer_metadata.id) AS composite_buyer
ON composite_data.value = composite_buyer.value
I haven't tested it but it's probably close.
For reference, here is the page on BigQuery JOINs. And have you seen this SO?

Need to add FK constraint to table, while keeping existing data's relation to another table

I currently have this schema, along with some data in both tables:
animal table pet_accessories table
+---------------+---------+ +-----------------------+-----------+
| animal_key | type | | pet_accessories_key | animal |
+---------------+---------+ +-----------------------+-----------+
| 1 | Dog | | 1 | Dog |
| 2 | Cat | | 2 | Bird |
| 3 | Bird | | 3 | Cat |
+---------------+---------+ | 4 | Cat |
+-----------------------+-----------+
but need to add a relation between the tables with a FK constraint from pet_accessories to the animal table instead. Ultimately, this is what I'd need:
animal table pet_accessories table
+---------------+---------+ +-----------------------+---------------+
| animal_key | type | | pet_accessories_key | animal_key |
+---------------+---------+ +-----------------------+---------------+
| 1 | Dog | | 1 | 1 |
| 2 | Cat | | 2 | 3 |
| 3 | Bird | | 3 | 2 |
+---------------+---------+ | 4 | 2 |
+-----------------------+---------------+
I have tried adding a new key column to my existing pet_accessories table, but having trouble with the logic that would set this animal_key correctly:
+-----------------------+-----------+--------------+
| pet_accessories_key | animal | animal_key |
+-----------------------+-----------+--------------+
| 1 | Dog | |
| 2 | Bird | |
| 3 | Cat | |
| 4 | Cat | |
+-----------------------+-----------+--------------+
I understand that SQL is primarily a set-orientated language - it's generally a bad idea to use a loop in it. I have also read that I could probably use cursors instead, although I'm not too familiar with them.
Question is, what is the best way to loop thru the data in pet_accessories.animal and compare with animals.type so that I can finally set pet_accessories.animal_key = animal.animal_key for all existing pet_accessories records? In other words, how do I:
for each record in pet_accessories
for each record in animal
if pet_accessories.animal == animal.type
then pet_accessories.animal_key = animal_animal_key
First, add the column:
alter table pet_accessories add animal_key integer;
Then, update the column:
update pa
set animal_key = a.animal_key
from pet_accessories pa join
animals a
on pa.animal = a.type;
Then, check to be sure everything is what you want.
Then, delete the old columns:
alter table pet_accessories drop column animal;
Then add the foreign key constraint:
alter table add constraint fk_animal_key
foreign key (animal_key) references animal(animal_key);

How to create view with multiple joins on same table

In my database I have these two tables:
Person
+----+---------+---------+
| pk | name | sirname |
+----+---------+---------+
| 1 | john | leno |
| 2 | william | wallice |
| 3 | eva | apple |
| 4 | walter | white |
+----+---------+---------+
Request
+----+-------------+----------+---------------+---------+---------+
| pk | requestdate | accepted | requestperson | parent1 | parent2 |
+----+-------------+----------+---------------+---------+---------+
| 1 | 1/1/2014 | Y | 1 | 2 | 3 |
| 2 | 1/2/2014 | N | 4 | NULL | NULL |
+----+-------------+----------+---------------+---------+---------+
To get the requests I do:
SELECT *
FROM request
LEFT JOIN person p_subject ON requestperson = p_subject.pk
LEFT JOIN person p_parent1 ON parent1 = p_parent1.pk
LEFT JOIN person p_parent2 ON parent2 = p_parent2.pk
This works perfect but when I want to create a VIEW:
CREATE VIEW v_request AS
SELECT *
FROM request
LEFT JOIN person p_subject ON requestperson = p_subject.pk
LEFT JOIN person p_parent1 ON parent1 = p_parent1.pk
LEFT JOIN person p_parent2 ON parent2 = p_parent2.pk
I get this error: ORA-00957: duplicate column name
I do not want to rename all columns manually. How can I fix this?
Your view would consist of:
three columns with the columnname pk
three columns with the columnname name (which is not a good columnname)
three columns with the columnname sirname
because the tablealiases will not be prepended automatically (which the error ORA-00957: duplicate column name states exactly)
I am quite sure you will have to rename them manually to subject_pk, subject_name, subject_sirname and so on.

mysql GROUP_CONCAT duplicates

I make my join from a farmTOanimal table like this. There is a similar farmTotool table
id | FarmID | animal
1 | 1 | cat
2 | 1 | dog
When I join my tables in a view, I get a result that looks like this
FarmID | animal | tool
1 | cat | shovel
1 | dog | shovel
1 | cat | bucket
1 | dog | bucket
Now, I do GROUP BY FarmID, and GROUP_CONCAT(animal) and GROUP_CONCAT(tool), i get
FarmID | animals | tools
1 | cat,dog,cat,dog | shovel,shovel,bucket,bucket
But, what I really want is a result that looks like this. How can I do it?
FarmID | animals | tools
1 | cat,dog | shovel,bucket
You need to use the DISTINCT option:
GROUP_CONCAT(DISTINCT animal)