which is faster select+ update or delete+insert in sql? - sql

I just got stuck in a problem, where there are two ways of solving this.
Let me first explain the case,
I have a DB table consisting of some columns say id, name, address, priority. Here name and address is not unique but name + address + priority is unique.
Input provided to me is name and list of addresses. Now, what I have to do is to arrange name and address in the same order as given in input in my DB table.
There are two ways of solving:
selecting on the basis of name and address and make update queries for those data which are changed and execute them.
delete the data corresponding to name and address from table and insert the data with new priority.
I know that one update is faster than delete + insert but here in this case there is one select query too.
My intuition is that 1st method will be more fast but I don't have any technical details about it.
Am I missing something?

Related

How can I use record content from one table to update another, without a join option?

I need to update values in a column in a specific table that exists in all our databases, but do not know the name of the column as it is user-generated.
I have two tables: one of them with user-generated columns tab_Case. In this table there is a column attachment that I need to update if the following condition applies: WHERE attachment = '0' (if true then the value needs to be changed to NULL).
In its simplest form the update query would look something like this:
UPDATE tab_Case
SET attachment = 'NULL'
WHERE attachment = '0'
This table is used in all our databases, so I need to write a query general enough to be usable across all of them.
The problem is that as the table uses user-generated columns, I have no way of knowing what the exact name is of concerned column-type, and exactly how many of those columns exist in the table.
I can, however, find out the type of the column by looking it up in another table tbl_itemPart inner joined with tbl_ValueType, like this:
SELECT ip.DbReference, ip.DbTableName, vt.ValueDescription
FROM tbl_itemPart ip
INNER JOIN tbl_ValueTypes vt ON ip.ValueTypeId = vt.ValuetypeId
WHERE vt.ValueDescription = 'file'
AND ip.DbTableName = 'tab_Case'
The columns I need are always of type 'file' and as the tab_Case table is referenced in tbl_ItemPart it is easy to find out 1) if any columns of type 'file' exist in this table, and 2) when true, what their respective names are.
So great, now I know the names of the columns that I need to potentially update. But, this is where I get lost: how do I use that information in my update query?
How do I write a script that first checks the tbl_itemPart for existence of any columns in tab_Case of type ' file', then retrieves the actual values (= names of those columns) from the DbReference column in tbl_itemPart and then finally uses those values in the update query for tab_Case?
Remember that this scripts needs to automatically do this for each of our databases, so I do not want to look up column names manually per database and then adjust my script accordingly for each of the databases.
I am very new to programming, and may be missing something very obvious, but so far I haven't been able to find a solution, or any relevant information to help me on my way.

SQL Best way to return data from one table along with mapped data from another table

I have the following problem.
I have a table Entries that contains 2 columns:
EntryID - unique identifier
Name - some name
I have another EntriesMapping table (many to many mapping table) that contains 2 columns :
EntryID that refers to the EntryID of the Entries table
PartID that refers to a PartID in a seprate Parts table.
I need to write a SP that will return all data from Entries table, but for each row in the Entries table I want to provide a list of all PartID's that are registered in the EntriesMapping table.
My question is how do I best approach the deisgn of the solution to this, given that the results of the SP would regularly be processed by an app so performance is quite important.
1.
Do I write a SP that will select multiple rows per entry - where if there are more than one PartID's registered for a given entry - I will return multiple rows each having the same EntryID and Name but different PartID's
OR
2.
Do I write a SP that will select 1 row per entry in the Entries table, and have a field that is a string/xml/json that contains all the different PartID's.
OR
3. There is some other solution that I am not thinking of?
Solution 1 seems to me to be the better way to go, but I will be passing lots of repeating data.
Solution 2 wont pass extra data, but the string/json/xml would need to be processed additionally, resuling in larger cpu time per item.
PS: I feel like this is quite a common problem to solve, but I was unable to find any resource that can provide common solutions or some pros/cons to different approaches.
I think you need simple JOIN:
SELECT e.EntryId, e.Name, em.PartId
FROM Entries e
JOIN EntriesMapping em ON e.EntryId = em.EntryId
This will return what you want, no need for stored procedure for that.

How to construct an sqlite table that assign and returns IDs to any name?

I would like to have an sqlite table that maps names into unique IDs. I can create this table in the following way:
CREATE TABLE name_to_id (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)
With a select statement I can get the row containing a needed name and get from this row the corresponding ID.
The problem appears if I try to get ID for a name that is not yet in the table. The expected behavior in this case is that the new name will be added and its newly generated ID will be returned. I have two possible solutions/implementations of that.
The first solution is trivial:
We check if name is in the table.
If not we insert a row with the name.
We select the row with the name and read the needed ID from that row.
I do not like this solution because it can happen that the first process checks if the name in the table, it sees that the name is not there, meanwhile another process adds the name to the table and then the first process tries to add the same name.
The second solution seems to be better:
For any name we use insert if not exist.
We select from the table the row containing the name and get its ID.
Is the second solution optimal or there are better solutions?
The normal way to avoid duplicate entries in a table is to create an unique constraint. The database will then check for you if the record is already there and fail if so. That should be the best in terms of reliability and performance.
Next, the SQLite FAQ suggests to use the function last_insert_rowid() to fetch the ID instead of running a second query. This is actually the first question of the FAQ at all ;)
In pseudocode, the first solution looks like this:
cursor = db.execute("SELECT id FROM name_to_id WHERE name = ?", name)
if cursor.has_some_row:
id = cursor["id"]
else:
db.execute("INSERT INTO name_to_id(name) VALUES(?)", name)
id = db.last_insert_rowid
and the second like this:
db.execute("INSERT OR IGNORE INTO name_to_id(name) VALUES(?)", name)
cursor = db.execute("SELECT id FROM name_to_id WHERE name = ?", name)
id = cursor["id"]
The first solution requires a transaction around both commands, but this would be a good idea for the second solution, too, to avoid the overhead of multiple implicit transactions.
The second solution requires a unique constaint on name, but this would be a good idea for the first solution, too, for correctness and to speed up the name lookups.
Both solution use two SQL statements, and have similar speed.
(The second searches the row two times, but that data is cached.)
So there isn't anything obvious that makes one better that the other.

Using SQL databases I need to gather data for a client from multiple sources

I have multiple databases that contain pieces of data that I need to collect on my clients. Without giving any specific examples, due to confidentiality of the actual data, I will simply refer to what the field names are.
My Master table and three other tables contain the following columns -
Social Security Number,
Medicare Number,
Medicaid Number,
Phone Number,
Date of Birth,
Last Name,
First Name
The goal is to read a master record and, if all of the specified fields do not contain data, go and look at the other data sources to see if one of them DO contain the missing data.
Let me tell you an example of what the problem might be and see what suggestions you can give me to help me achieve my goal. In my example I will call the master table Table 1.
Table 1 - Is missing the DOB, SSN & Medicaid# for this record.
Table 2 - Contains the DOB, Medicare# and Last & First Name.
Table 3 - Has DOB, Medicaid#, Phone Number and Last & First Name.
Table 4 - DOB, SSN, Medicare#, and Phone Number, and Last & First Name.
Currently, I am doing the following:
I created a view called View 1 to combine all of the tables together. The uncommon fields are simply NULL for the tables no containing the field.
I have nested case statements for each of the desired fields. I look to see if the field in Table 1 is NULL, I begin doing a SubSelect statement to look for a matching record in the View 1 for each of the possible matching fields along with any secondary field to double check when needed - like if I do just DOB and Last & First Name matches.
I have a temporary table that gets updated with the findings prior to me running through the checks again. I run through it multiple times since the first time through it might not have had a hit with one field, but the second time through it would find a match.
Does anyone see a better way of doing it thn what I have described?
This is the part that loses me:
I have a temporary table that gets updated with the findings prior to
me running through the checks again. I run through it multiple times
since the first time through it might not have had a hit with one
field, but the second time through it would find a match.
Without that I would suggest left joining the tables to the master then using COALESCE() to find your best NOT NULL value.
COALESCE(Table_1.DOB,Table_2.DOB,Table_3.DOB,Table_4.DOB)

Using a foreign key in Oracle SQL to display text data

New to Oracle SQL and I assume that this is a very straight forward question but I can't find a direct answer. I have an employees table in my database. One of the columns is 'emp_state' which is to show the State in which the employee resides. I also have a 'Customer' table and an 'office' table, which also both have a 'State' field. To reduce the amount of redundant data in my database, I have created a 'State' table, which will have all the states with a corresponding ID. I want to reference this table in the other tables as mentioned. When setting up my table, what should I define as the foreign key in the relevant tables? Should it be 'State_id' or 'State_name'? I want the state name to appear in any queries that are run, rather than the state ID which would be meaningless to a user.
Thank you!
You should use state_id. If is much faster to join on a INT then a VARCHAR.
If you need the name if a state the you should JOIN on the table and get it
If you are planing to update the state name then you need to update all the relate tables. If you have a id then you just need to update the name column.
You would probably not have the same state name twice. But what if you do? Then you must change it or append some strange number on the state name.
So bottom line: Always use the id