Insert SQL Server row into specific position in formatted table - sql

I'm new at creating database and currently trying to accomplish something that is really necessary for me.
Lets say I have a Database "Customer" with 300 rows all with a unique identifier called Id_.
Id_ | Customer | Postal | Country |
200 | Mica Sa. | 99582 | USA
201 | Shum Jr. | 10258 | USA
202 | Carl Ro. | 45697 | USA
203 | Brad Mi. | 24761 | USA
If i delete a row number 202 using:
DELETE FROM Customer
WHERE Id_ = 202;
I Get:
Id_ | Customer | Postal | Country |
200 | Mica Sa. | 99582 | USA
201 | Shum Jr. | 10258 | USA
203 | Brad Mi. | 24761 | USA
But when I try to insert a row using:
INSERT INTO Customer (Id_, Customer, Postal, Country)
VALUES (202, 'Peter R.', 08574, 'USA');
I get the row randomly inserted in the database, so my question is how do I insert this row exactly after 201(Id_) and before 203(Id_)?

To help you clear some things up:
ID field seems to be int and not unique identifier
Insert statements are not made randomly in the DB, they go to the last record. E.G if you have 201,203 and you insert 202 it will go after 203.
The way you select the records (and thus they fetched and displayed) is another thing. You may run a query that return 202 before 203 but this doesn't mean that this is the way that are stored in the DB
If ID are actually of type int I recon you make them auto incremental
Select * from Customer Order by Id_ Desc

Related

“Is there an Access SQL code/query for concatenating first letter plus a unique ID number and insert into a new column? [duplicate]

This question already has answers here:
Customized Auto-Number IDs for tables?
(2 answers)
Closed 3 years ago.
First of all, I am quite new to SQL and Microsoft Access.
I am setting a database in Access. My database collects information from four different departments. I store my data through forms. My main table (Business) stores information (department) using a Combo Box saving a number instead of text.
I want to have a column (similar to CODE ID already available in the table above) which shows the initial letter from a field (name Department) + a number.
Ie. In table "Business", I want to display a Code ID which contains the initials of column Department plus a number code (department order number ascending). I want to have this every time i add information.
+===============+=================+=========+==+
| DEPARTMENT | PARTNER | CODE ID | |
+===============+=================+=========+==+
| Data_Analysis | John Doe | D001 | |
+---------------+-----------------+---------+--+
| Marketing | Jane Doe | M001 | |
+---------------+-----------------+---------+--+
| Finance | Alex Mustermann | F001 | |
+---------------+-----------------+---------+--+
| Operations | Juan Perez | O001 | |
+---------------+-----------------+---------+--+
| Finance | Barack Trump | F002 | |
+---------------+-----------------+---------+--+
| Finance | Mark Merkel | F003 | |
+---------------+-----------------+---------+--+
| Marketing | Peggy Hilton | M002 | |
+---------------+-----------------+---------+--+
| Operations | Max Mustermann | O002 | |
+---------------+-----------------+---------+--+
| Operations | | OXXX | |
+---------------+-----------------+---------+--+
The values in column CODE ID are those I would like to have display every time I add a new row (new department order). I need this type of code for tracking my number of orders in each department and use it as a unique code for any inquires with partners. I dont want to have it as the primary key id.
Thanks in advance!
If you rethink the schema slightly it becomes trivial; instead of having the column with the ID and code combined, just keep a running count when inserting:
INSERT INTO business(department, name, code) SELECT Forms!Department, Forms!Name, COUNT(*)+1 FROM business WHERE name=Forms!Name
Then when you pull the information out:
SELECT department, name, LEFT(1, department) & code

SQL Help - Insert into a table, data from two different tables, based on a reference table

I have a four tables I am working with. One of the tables is empyt (ATM) with three columns (ID, Cust_AcctID, Brch_CtyID) and I would like to insert data into the Cust_AcctID and Brch_CtyID columns of this table.
ID | Cust_AcctID | Brch_CtyID
The second table (Cust_Acct) also has three columns (ID, Customer and Account)
The Customer and Account columns hold string data. The ID value in this column is what I am looking to have inserted into the ATM table in the Cust_AcctID column
ID | Customer | Account
1 | John Doe | Checking
2 | John Doe | Saving
3 | Jane Doe | Checking
4 | Jane Doe | Plan24
The Third table (Brch_Cty) has three columns as well (ID, Branch and City)
The Branch and City columns hold string data. The ID value in this column is what I am looking to have inserted into the ATM table in the Brch_CtyID column.
ID | Branch | City
1 | Main Branch | New York
2 | Second Branch | New York
3 | Main Branch | Chicago
4 | Uptown Branch | Detroit
The fourth table is a reference table that holds all the valid combinations Of (Customers, Account) and (Branch, City). All data in these columns are strings.
Customer | Account | Branch | City
John Doe | Checking | Main Branch | New York
John Doe | Savings | Second Branch | New York
John Doe | Checking | Uptown Branch | Detroit
Jane Doe | Checking | Uptown Branch | Detroit
Using the data from table 4, I would like to insert into the ATM table the the data from the ID column from the Cust_Acct Table into the Cust_AcctID column where it matches the data in the fourth table. The same goes for the Brch_Cty table ID to be inserted into the Brch_CtyID column
So the ATM table should look like this
ID | Cust_AcctID | Brch_CtyID
1|1|1
2|2|2
3|1|4
4|3|4
Could you please help me with building a SQL statement for this. I am really stuck figuring this one out. Thanks for any help given.
Can you try the following :
Select ca.ID,bc.ID
From dbo.temp t Inner join dbo.Cust_Acct ca on ca.Customer=t.Customer AND
ca.Account=t.Account
inner join dbo.Brch_City bc on bc.Branch=t.Branch AND bc.City=t.City
Where ca.Customer=t.Customer AND ca.Account=t.Account AND bc.Branch=t.Branch
AND bc.City=t.City
Hope this helps. :)

Remove newest redundant row and update timestamp

I'm working with a SQLite database that receives large data dumps on a regular basis from several sources. Unfortunately, those sources aren't intelligent about what they dump, and I end up with a lot of repeated records from one time to the next. I'm looking for a way to remove these repeated records without affecting the records that have legitimately changed from the past dump to this one.
Here's the general structure of the data (_id is the primary key):
| _id | _dateUpdated | _dateEffective | _dateExpired | name | status | location |
|-----|--------------|----------------|--------------|------|--------|----------|
| 1 | 2016-05-01 | 2016-05-01 | NULL | Fred | Online | USA |
| 2 | 2016-05-01 | 2016-05-01 | NULL | Jim | Online | USA |
| 3 | 2016-05-08 | 2016-05-08 | NULL | Fred | Offline| USA |
| 4 | 2016-05-08 | 2016-05-08 | NULL | Jim | Online | USA |
| 5 | 2016-05-15 | 2016-05-15 | NULL | Fred | Offline| USA |
| 6 | 2016-05-15 | 2016-05-15 | NULL | Jim | Online | USA |
I'd like to be able to reduce this data to something like this:
| _id | _dateUpdated | _dateEffective | _dateExpired | name | status | location |
|-----|--------------|----------------|--------------|------|--------|----------|
| 1 | 2016-05-01 | 2016-05-01 | 2016-05-07 | Fred | Online | USA |
| 2 | 2016-05-15 | 2016-05-01 | NULL | Jim | Online | USA |
| 3 | 2016-05-15 | 2016-05-08 | NULL | Fred | Offline| USA |
The idea here is that rows 4, 5, and 6 exactly duplicate rows 2 and 3 except for the timestamps (I'd need to compare by all three fields - name, status, location). However, row 3 does not duplicate row 1 (status changed from Online to Offline), so the _dateExpired field is set in row 1, and row 3 becomes the most recent record.
I'm querying this table with something like this:
SELECT * FROM Data WHERE
date(_dateEffective) <= date("now")
AND (_dateExpired IS NULL OR date(_dateExpired) > date("now"))
Is this sort of reduction possible in SQLite?
I am still a beginner to SQL and database design in general, so it's possible that I haven't structured the database in the best way. I'm open to suggestions there as well...I'm going for the ability to query data at a given point in time - for example, "what was Jim's status around 2016-05-06?"
Thanks in advance!
Consider using a staging table where the dump file goes into a DumpTable (regularly cleaned out before each dump) and then an INSERT...SELECT query migrates to your final table.
Now the SELECT portion maintains a correlated subquery (to calculate new [_dateExpired] for needed rows) and derived table subquery (to filter out non-dups according to your criteria). Finally, the LEFT JOIN...NULL with FinalTable is to ensure no duplicate records are appended, assuming [_id] is a unique identifier. Below is the routine:
Clean Out DumpTable
DELETE FROM DumpTable;
Run Dump Routine to be appended into DumpTable
Append Records to FinalTable
INSERT INTO FinalTable ([_id], [_dateUpdated], [_dateEffective], [_dateExpired],
[name], status, location)
SELECT d.[_id], d.[_dateUpdated], d.[_dateEffective],
(SELECT Min(date(sub.[_dateEffective], '-1 day'))
FROM DumpTable sub
WHERE sub.[name] = DumpTable.[name]
AND sub.[_dateEffective] > DumpTable.[_dateEffective]
AND sub.status <> DumpTable.status) As calcExpired
d.name, d.status, d.location
FROM DumpTable d
INNER JOIN
(SELECT Min(DumpTable.[_id]) AS min_id,
DumpTable.name, DumpTable.status
FROM DumpTable
GROUP BY DumpTable.name, DumpTable.status) AS c
ON (c.name = d.name)
AND (c.min_id = d.[_id])
AND (c.status = d.status)
LEFT JOIN FinalTable f
ON d.[_id] = f.[_id]
WHERE f.[_id] IS NULL;
-- INSERTED RECORDS:
-- _id _dateUpdated _dateEffective _dateExpired name status location
-- 1 2016-05-01 2016-05-01 2016-05-07 Fred Online USA
-- 2 2016-05-01 2016-05-01 Jim Online USA
-- 3 2016-05-08 2016-05-08 Fred Offline USA
Is this sort of reduction possible in SQLite?
The answer to any "reduction" question in SQL is always Yes. The trick is to find what axes you're reducing along.
Here's a partial solution to illustrate; it gives the first Online date for each name & location.
select min(_dateEffective) as start_date
, name
, location
from Data
where status = 'Online'
group by
name
, location
With an outer join back to the table (on name & location) where the status is 'Offline' and the _dateEffective is greater than start_date, you get your _dateExpired.
_id is the primary key
There is a commonly held misunderstanding that every table needs some kind of sequential "ID" number as a primary key. The key you really care about is known as a natural key, 1 or more columns in the data that uniquely identify the data. In your case, it looks to me like that's _dateEffective, name, status, and location. At the very least, declare them unique to prevent accidental duplication.

UNIQUE - way to have unique rows in table?

I have problem with unique rows in db table, now it is posible to do that:
id | Name | LastName | City
-------------------------------------
1 | John | Moore | London
2 | John | Moore | London
when i use UNIQUE attribute in all columns i have errors inserting second Moore even it is different Name :/
how use UNIQUE (or maybe INDEX?) to do something like that in my table in db:
id | Name | LastName | City
-------------------------------------
1 | John | Moore | London
2 | Jake | Moore | London
3 | John | Keen | London
4 | John | Moore | London //but good error when inserting the same row
Sorry if question is easy, but i am beginner at sql, and have problems with find some good example with using a UNIQUE like a want:/
or maybe I must just before inserting a new row selecting a table from db and check if it exist?
Remove the unique index on the individual column and make it on both columns together, like this:
CREATE UNIQUE INDEX ixFullName ON yourTable (LastName, Name);

Need select query

Consider the following table structure with data -
AdjusterID | CompanyID | FirstName | LastName | EmailID
============================================================
1001 | Sterling | Jane | Stewart | janexxx#sterlin.com
1002 | Sterling | David | Boon | dav#sterlin.com
1003 | PHH | Irfan | Ahmed | irfan#phh.com
1004 | PHH | Rahul | Khanna | rahul#phh.com
============================================================
Where AdjusterID is the primary key. There are no. of adjusters for a company.
I need to have a query that will list single adjuster per company. i.e. I need to get the result as -
========================================================
1001 | Sterling | Jane | Stewart | janexxx#sterlin.com
1003 | PHH | Irfan | Ahmed | irfan#phh.com
========================================================
If any one could help me that will be great.
One way:
SELECT * FROM Adjusters
WHERE AdjusterID IN(SELECT min(AdjusterID)
FROM Adjusters GROUP BY CompanyID)
There are a handful of other ways involving unions and iteration, but this one is simple enough to get you started.
Edit: this assumes you want the adjuster with the lowest ID, as per your example
I know the answer from Jeremy is a valid one, so I will not repeat it. But you may try another one using a so called tie-breaker:
--//using a tie-breaker. Should be very fast on the PK field
--// but it would be good to have an index on CompanyID
SELECT t.*
FROM MyTable t
WHERE t.AdjusterID = (SELECT TOP 1 x.AdjusterID FROM MyTable x WHERE x.CompanyID = t.CompanyID ORDER BY AdjusterID)
It could be better performance-wise. But even more useful it is if you had another column in the table and you wanted to select not just one for each company but the best for each company using some other column ranking as a criteria. So instead of ORDER BY AdjusterID, you would order by that other column(s).