Update existing database values from spreadsheet - sql

I have an existing MSSQL database where the values in some columns need updating according to a spreadsheet which contains the mappings of old data and new data.
The spreadsheet is like this:
| OLD DATA | NEW DATA |
RECORD | A | B | C | D | A | B | C | D |
1 |OLD|OLD|OLD|OLD|NEW|NEW|NEW|NEW|
2 |OLD|OLD|OLD|OLD|NEW|NEW|NEW|NEW|
Where ABCD are the column names, which relate to the database, and OLD / NEW relates to the data.
Thus for each line (approx 2500 rows)
The database values that match OLD in each column, need to be changed to NEW
My current thoughts are to do it in a similar way to this:
SQL Statement that Updates an Oracle Database Table from an Excel Spreadsheet
Essentially getting Excel to formulate a list of replace statements, though this feels like a horribly convoluted way to deal with the problem!
Is there a way to have SQL cycle though each row of the spreadsheet, check all records for a=old, b=old2, c=old3, d=old4 and then replace those values with the appropriate a=new, b=new2, c=new3, d=new4?

You shouldn't need to loop through each row in the spreadsheet. You can use the OPENROWSET command, like in the answer you linked to, to load the spreadsheet data into a sort of temporary table. You can then run a regular UPDATE statement against that table.
It would look something like this
UPDATE YourTable
SET YourTable.A = ExcelTable.NewDataA,
YourTable.B = ExcelTable.NewDataB,
YourTable.C = ExcelTable.NewDataC,
YourTable.D = ExcelTable.NewDataD
FROM YourTable
INNER JOIN OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=C:\foldername\spreadsheetname.xls;',
'SELECT column1name, column2name, column3name, column4name
FROM [worksheetname$]') AS ExcelTable
ON YourTable.ID = ExcelTable.ID
WHERE (YourTable.A = ExcelTable.OldDataA
AND YourTable.B = ExcelTable.OldDataB
AND YourTable.C = ExcelTable.OldDataC
AND YourTable.D = ExcelTable.OldDataD)

Looks like Jeff got you the answer you needed, but for anyone looking to update a database from a Google Sheet, here's an alternative, using the SeekWell desktop app. For a version of this answer with screen shots, see this article.
Get the right rows and columns into the spreadsheet (looks like #sbozzie already had this)
Write a SQL statement that SELECT 's all the columns you want to be able update in your sheet. You can add filters as normal in the WHERE clause.
Select 'Sheets' the top of the app and open a Sheet. Then click the destination icon in the code cell and select "Sync with DB"
Add your table and primary key
In the destination inputs, add your table name and the primary key for the table.
Running the code cell will add a new Sheet with the selected data and your table name as the Sheet name. Please note that you must start your table in cell A1. It's a good idea to include an ORDER BY.
Add an action column
Add a "seekwell_action" column to your Sheet with the action you'd like performed for each row. Possible actions are:
Update - updates all columns in the row (unique primary key required)
Insert - adds the row to your database (you need to include all columns required for your database)
Sync - An Update action will be taken every time the query runs, on a schedule (see "5. Set Schedule" below)
Complete - status after the schedule has run (see below) and the actions have been taken. The new data should now be in your database. Note that 'Sync' actions will never show complete, as they run every time the schedule runs. To stop a 'Sync' action, change it manually.
Set Schedule
To execute the actions, select the clock icon at the top of the application, indicate the frequency and exact time, and click 'Save.' You can manage your schedule from the inserted 'RunSheet' (do not delete this sheet or you will need to reset your schedule) or from seekwell.io/profile. If you need to run the actions immediately, you can do so from /profile.
Gotchas
You need to start your table in cell A1.
Snowflake column names are case sensitive. Be sure to respect this when specifying the primary key, etc.
If your server is behind a firewall, you will need to whitelist SeekWell's static IP address to use scheduling. See more about whitelisting here.

Related

BigQuery Create Table Query from Google Sheet with Variable item string field into Repeated Field

I hope I explain this adequately.
I have a series of Google Sheets with data from an Airtable database. Several of the fields are stringified arrays with recordIds to another table.
These fields can have between 0 and n - comma separated values.
I run a create/overwrite table SELECT statement to create native BigQuery tables for reporting. This works great.
Now I need to add the recordIds to a Repeated field.
I've manually written to a repeated field using:
INSERT INTO `robotic-vista-339622.Insurly_dataset.zzPOLICYTEST` (policyID, locations, carrier)
VALUES ('12334556',[STRUCT('recordId1'),STRUCT('recordId2')], 'name of policy');
However, I need to know how I to do this using SELECT statement rather than INSERT. I also need to know how to do this if you do not know the number of recordIds that have been retrieved from Airtable. One record could have none and another record could have 10 or more.
Any given sheet will look like the following, where "locations" contains the recordIds I want to add to a repeated field.
SHEETNAME: POLICIES
|policyId |carrier | locations |
|-----------|-----------|---------------------------------|
|recrTkk |Workman's | |
|rec45Yui |Workman's |recL45x32,recQz70,recPrjE3x |
|recQb17y |ABC Co. |rec5yUlt,recIrW34 |
In the above, the first row/record has no location Id's. And then three and two on the subsequent rows/records.
Any help is appreciated.
Thanks.
I'm unsure if answering my own question is the correct way to show that it was solved... but here is what it took.
I create a Native table in BigQuery. the field for locations is a string, mode repeated.
Then I just run an overwrite table SELECT statement.
SELECT recordId,Name, Amount, SPLIT(locations) as locations FROM `projectid.datasetid.googlesheetsdatatable`;
Tested and I run linked queries on the locations with unnest.

How to use UPDATE IIF

I am using SQL in MS-Access.
I created some queries that analyze if a code is present in two different excel spreadsheets and generate a new table, informing "yes" or "no" for each comparison.
However, sometimes, a certain code appears in just one table, but after a while (when someone update the excel spreadsheets), that code appears.
I already have a query that makes this comparison, but it doesn't work for those codes that are introduced in the table AFTER the comparison has already been made.
So, I would like to create a query that uses an UPDATE, checking if the given code is now in both tables, and if it is, it would update the comparison column of my table.
This is the query I created for this, but it is not working:
UPDATE
comparationTable
SET
col_comp = IIf(spreadSheet1.code = spreadSheet2.code),"Yes","******No******")
WHERE
code1 = code2;
Note: code1 and code2 are columns that only show the code coming from excel spreadsheet1 and excel spreadsheet2, respectively.
Edit: Here's the images of the two spreadsheets (sp1, sp2) and the comparation table:
Too many parenthesis - must always be in pairs. Field names are not correct. The WHERE clause is not appropriate - records without value in Code2 will not update with any value.
UPDATE comparationTable SET col_comp2 = IIf(code1 = code2, "Yes", "******No******")

SQL Query to add timestamp

I have a Table in our ERP system that tracks the status of shop orders. It has the open date (column name ORGDUE_10) and Status column (STATUS_10) which has codes 1-6, and status 3 is an open order, status 4 is closed (the rest of the codes do not matter for this application). Unfortunately, this table does not have a timestamp column where I can get the date when the order is closed. I need to determine if multiple Shop Orders were closed (STATUS_10 changed from 3 to 4) on time or if they went past the due date (ORGDUE_10).
Any ideas how I could do a query that will accomplish this? I assume I need a another table – write the data to it and then some kind of trigger?
I am using VS2015. The Table Name that I cannot edit is Order_Master
STATUS_10 ORDNUM_10 PRTNUM_10 CURDUE_10
4 | 50015246 |ASY5670 | 9/4/2017
3 | 50016983 |ASY5699 | 5/15/2017
I figured it out (I think). Here is the code I used which seems to do the trick. this code will update, insert, and conditionally timestamp (datestamp) two different tables on two different servers. I hope this makes sense and helps someone else. I appreciate the help given #Jonathan Leffler, sorry I didn't make it easy on you.
MERGE server2.dbo.table2 AS target /* the added server.dbo is in the event the two tables are
on different sql servers*/
USING server1.dbo.table1 AS source ON (target.column-t = source.column-s) /*
column-t is the target column and column-s is the matching source column */
WHEN MATCHED AND (conditional column) AND (antoher conditional column) THEN
UPDATE SET
column-t = source.column-s, column-t (for datestamp) = (GETDATE())
WHEN NOT MATCHED AND (conditional column) AND (antoher conditional
column)THEN /* you cannot use a WHERE clause in a MERGE but you can set
up similar conditions in the WHEN statements */
INSERT (target columns)
VALUES (source columns in same order as target columns);

how can I link rows of a SQL table for some columns but not others?

I have a table of values in excel that I want to put into sql as a lookup table. the table looks like this:
the sql table looks like this:
having this in SQL, I now want to never use the excel file ever again.
I also need the ability to change the parameters, but some of them in the excel file were linked by merging the cells and thereby shared the same value, if it changed for one it changed for all.
for example: when I change Parameter B for Product 1, I need it to change it for Products 2, 3, 4, and 5 because they share the same cell in the excel table. And if I change parameter A for Product 2, It only changes for product 2 and 3. I am looking for a SQL Query solution. I have the ability to change the table structure as well.
Here goes my example query:
Update [Table] Set [Parameter_A] = '{new_parameter_tag}'
Where [product] = '{selected_product_tag}'
except I want to have the Where include all the rows that share the same cell from the excel table.
I want to be able to update the SQL table for multiple products at a time based on if they share the same cell for that parameter in the excel file.
here is my initial guess at an answer:
Select [{Parameter}],[Product],[Extra_column]
From [Table]
Where [Product] = '{selected_product}'
this returns one row and [Extra_column] that contains a grouping number shared by others in the same cell grouping. this then gets stored as {Extra_column}. then:
Update [Table] Set [{Parameter}] = '{new_parameter_value}'
Where [product] = '{selected_product}' Or [Extra_column] = '{Extra_Column}'
this requires two queries and also means that i need twice as many columns as i had before. I am looking for something a little more elegant.
This is SQL Server 2012 and the {} indicate a value that I am passing in form a script.
I ended up doing something similar to what I had above, the user enters the group they want to edit (it's pretty easy to pick out which one you want when viewing the table) as:
Update [table]
Set [{Parameter}]={NewValue}
Where [Extra_Column] = '{Extra_Column}'
I had to add three columns for the grouping indexes but over 43 parameters that doesn't add much to my table size. I did not take into account the fact that if I change a single parameter for a single product that would remove it from the "group" essentially for just that parameter, and later I would overwrite the changed value if I do a group change for that parameter. I could add in a check to only change values that match within that group but either way the user will have to be smart about what they do. luckily, they can see the table before they change it.

merge msaccess tables

How can i merge two identical tables of two msaccess identical db? For eg:
db1..table1
ID Name
1 Sanjana
2 Parul
3 Rohan
db2...table1
ID Name
1 Sarika
2 Deepak
I want to append the values of second table into first as follows:
ID Name
1 Sanjana
2 Parul
3 Rohan
4 Sarika
5 Deepak
The datatype for the ID field appears to be an autonumber. As such you can do the following:
INSERT INTO db1...table1
SELECT Name FROM db2...table1
You can use an append query:
INSERT INTO Table1 ( FName ) IN 'c:\docs\ltd.mdb'
SELECT A.FName
FROM A;
OK, heres an approach more suited to a beginner making use of the gui.
Backup both databases and store them away somewhere safe.
Do a compact and repair from the tools menu on both databases
Create a linked table in db1 pointing to the table in db2
To do this right click on some white space in the table view of database window and choose link table... Follow the wizard to select db2 and then select table1.
Use an append query to append the data from the linked table1 into the db1.table1
Click into the queries view of Access, create a new query in design view, change its type to Append (right click in free space where the tables appear and go to type->append) Then choose db1.table1 when prompted as the table to append to. Now add the linked table1 into the query, select the fields from which you want to take data (in the example it would just be Name). Note you do not want to take the id field across as this will need to be updated to follow on from where db1.table1 left off, im assuming this is set to autonumber.
Delete the linked table from db1
Im not 100% certain the sort order will be retained from db2.table1 when its appended to db1.table1 as in your example. In most database designs this wont be important but if it is someone else may be able to shed light - i imagine that if the ID field in both tables is also the primary key it will.
Well since it is access, you have two ways. the first is mentioned by LSFR Consulting
and the second would be to use the import wizard and tell the import to ignore the primary key column. That would merge the data from db2 into DB1 without having a primary key collision.
If this is a one time operation simple copy-n-paste will work.
Open both databases in MS Access. Open both tables. Select values to copy (right-click on Column header and Ctrl+C).
Proceed to target table. Make Name field selected in the last row (new record). For this purpose mouse over Name column left edge (cursor becomes a plus sign) and click to select the cell. Ctrl+V. Done.