Increment non unique field during SQL insert - sql

I'm not sure how to word this cause I am a little confused at the moment, so bear with me while I attempt to explain, I have a table with the following fields:
OrderLineID, OrderID, OrderLine, and a few other unimportant ones.
OrderLineID is the primary key and is always unique (which isn't a problem), OrderID is a foreign key that isn't unique (also not a problem), and OrderLine is a value that is not unique in the table, but should be unique for any OrderIDs that are the same...so if that didn't make sense, perhaps a picture...
OrderLineID, OrderID, OrderLine
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
For all OrderIDs there is a unique OrderLine. I am trying to create an insert statement that gets the max OrderLine value for a specific OrderId so I can increment it, but it's not working so well and I could use a little help. What I have right now is below, I build the SQL statement in a program and replace OrderID # with an actual value. I am pretty sure the problem is with the nested select statement, and incrementing the result, but I can't find any examples that do this since my Google skills are weak apparently....
INSERT INTO tblOrderLine (OrderID, OrderLine) VALUES
(<OrderID #>, (SELECT MAX(OrderLine)
FROM tblOrderLine WHERE orderID = <same OrderID #>)+1)
Any help would be nice.

This statement works in Access 2003. You would have to substitute your OrderID value in the WHERE clause.
INSERT INTO tblOrderLine (OrderID, OrderLine)
SELECT
s.OrderID,
s.MaxOrderLine + 1 AS NewOrderLine
FROM (
SELECT
OrderID,
Max(OrderLine) AS MaxOrderLine
FROM
tblOrderLine
WHERE
OrderID=1
GROUP BY
OrderID
) AS s;
I read the others' misgivings, and will leave the wisdom of this approach to you. It could get more interesting if you can have multiple users updating tblOrderLine at the same time.

Are you getting some type of error? Your SQL code seems to work fine for me.

Don't use a combination of VALUES and SELECT. Try:
INSERT INTO tblOrderLine (OrderID, OrderLine)
SELECT <OrderID #>, MAX(OrderLine)
FROM tblOrderLine
WHERE orderID = <same OrderID #>)+1
;

Adding a scalar to the result of a query isn't generally kosher. Try moving the "+1":
INSERT INTO tblOrderLine (OrderID, OrderLine) VALUES
(
<OrderID #>,
(SELECT MAX(OrderLine)+1 FROM tblOrderLine WHERE orderID = <OrderID #>)
)

Related

Query trying to select but get ambiguous error?

It runs but I select all the columns. Can someone explain to me why my first query doesn't work? I don't think I need a join. If I can get some help that would be good. To be quite honest I've never seen the error before. If it works with SELECT*, I don't understand why I have issues with select specific columns.
These are my tables:
create table product
(
pdt# varchar(10) not null,
pdt_name varchar(30) not null,
pdt_label varchar(30) not null,
constraint product_pk primary key (pdt#));
create table orders
(
pdt# varchar(10) not null,
qty number(11,0) not null,
city varchar(30) not null
);
And these are the values
insert into product values ([111,chair,chr]);
insert into product values ([222,stool,stl]);
insert into product values ([333,table,tbl]);
insert into orders values ([111,22,Ottawa]);
insert into orders values ([222,22,Ottawa]);
insert into orders values ([333,22,Toronto]);
Question is this:
c. List all [pdt#,pdt_name,qty] when the order is from [Ottawa]
I tried:
SELECT pdt#, pdt_name, qty FROM orders, product WHERE city='Ottawa';
I get column is ambiguously defined error. But when I run:
SELECT *, qty FROM orders, product WHERE city='Ottawa';
It runs but I select all the columns. Can someone explain to me why my first query doesn't work? I don't think I need a join. If I can get some help that would be good. To be quite honest I've never seen the error before. If it works with SELECT*, I don't understand why I have issues with select specific columns.
This is because both the tables have pdt# in common and you are selecting it in your query. In cases like these, you have to explicitly specify the table from which the column should be picked up.
You should also join the tables. Else you would get a cross-joined result.
SELECT p.pdt#, p.pdt_name, o.qty
FROM orders o join product p on o.pdt# = p.pdt#
WHERE o.city='Ottawa';
Your second query works because you are selecting all the columns from both the tables and ideally it should not be done. Always specify the columns you need when you are selecting from more than one table.

How to get one row from duplicated rows?

I have 2 tables SVC_ServiceTicket and SVC_CustomersVehicle
The table ServiceTicket has a column customerID which is a foreign key to CustomersVehicle.So in ServiceTicket column customerID can have duplicate values.
When I do
select sst.ServiceTicketID,sst.CustomerID
from ServiceTicket sst,CustomersVehicle scv
where sst.CustomerID=scv.CV_ID
then it gives me duplicate customerID.So my requirement is if there are duplicate values of customerID then I want the latest customerID and as well serviceticket of that corresponding(latest customerID)
For example in the below screenshot there are customerID 13 is repeating so in this case I want latest customerID as well as serviceticket so the values I want is 8008 and 13
Please tell me how to do
Use aggregate function MAX. Also I would recommend to use a JOIN.
SELECT MAX(sst.ServiceTicketID) AS ServiceTicketID,sst.CustomerID
FROM ServiceTicket sst JOIN
CustomersVehicle scv ON sst.CustomerVehicleID=scv.CV_ID
GROUP BY sst.CustomerID

Nested Select SQL statements in an Insert SQL statement

I'm trying to take values from a Cart(ID PK, Username PK, MenuID) table and an Order(ID PK,Username,Address) table and insert them into an OrderItem(OrderID, MenuID, OrderItemID PK) table.
Its the process of confirming the purchase. So I have to insert all the values from the cart into OrderItem and add the last inserted ID in the Order table
Here's where I'm stuck:
insert into OrderItem (MenuID, OrderID) Values (A,B)
A=(Select MenuID from Cart Where Username='Foris')
B=(Select last_insert_rowid() from Order)
I added the B and A to explain what I meant. I can't do it using using inner joins i think.
Here's an image of the database design
Thanks in advance
Have you tried this?
insert into OrderItem (MenuID, OrderID)
Select MenuID, last_insert_rowid()
from Cart
Where Username = 'Foris';
I am not sure what select last_insert_rowid() from Order is supposed to be. Well, I do know, that would return all the rows in Order with one column, the last_insert_rowid() whatever that value might be.
The above assumes that the previous statement was an insert into Order.

How to use SQL Merge populating Master Detail related tables

I've been searching and I've yet to find an example using merge for populating related tables.
The Northwind DB Order & OrderDetail tables could be used. (In our scenario, our tables are 3 levels deep.)
For simplicity let's say we have the following tables.
Orders
OrderID PK
OrderNumber
OrderDetails
OrderID - PK
OrderLineItemNumber PK - FK to Orders.OrderID field
OrderDetailDetails
OrderID - PK - FK to OrderDetails.OrderID
OrderLineItemNumber - PK - FK to OrderDetails.OrderLineItemNumber
OrderSequenceNumber - PK
Also, in this scenario, records get written to staging tables that are identical the tables above. The merge would need to merge records from the 3 staging tables to the 3 matching production tables.
The production Order table's OrderId will not share the staging Order tables OrderId value.
So if the merge conditions are met, then there must be an insert into the Order table to generate OrderId (set to identity) because OrderId is needed for the OrderDetail & OrderDetailDetails rows to be created.
Right now I've written a service in C# that does all this but it's not that performant.
MERGE was discovered so we're looking into it to see if it can be used in a situation such as this. Any tips or pointers would be greatly appreciated.
Thanks.
Edit: I am now using Output store values into a Temporary table called #MergeOutput.
Declare #MergeOutput Table
(
ActionType varchar(10),
InsertedOrderId int,
StagingOrderID int,
DeletedOrderId int
);
However, I need to do a Merge on all 3 tables. (Order, OrderDetail & OrderDetailDetails)
Also, these tables have more fields than just the Id's.
So I've started creating the 2nd Merge for the OrderDetail table.
MERGE OrderDetail AS OD
USING(
SELECT OrderID,
OrderLineItemNumber,
ProductId
FROM OrderDetail AS OD
where OrderId IN (Select StagingOrderID from #MergeOutput where ActionType = 'INSERT'
) AS src(OrderID,
OrderLineItemNumber,
ProductId
)
ON (OD.OrderId = src.Order AND OD.OrderLineItemNumber = src.OrderLineItemNumber)
WHEN NOT MATCHED By Target THEN
INSERT INTO <-- (This doesn't work no matter what I've tried so far.)
Select (Select Distinct InsertedOrderID from #MergeOutput where StagingOrderId = OrderID), src.OrderLineItemNumber, src.ProductId
;
I see the following errors with the code above.
"Incorrect syntax near the keyword 'into'
I need the functionality of the Merge to move records on all 3 tables
Looks like I've finally got this to working. I had to change the Insert statement to as follows.
Insert(OrderId, OrderLineItemId, ProductID)
Values((Select Distinct InsertedOrderID from #MergeOutput where StagingOrderId = OrderID), src.OrderLineItemNumber, src.ProductId)
I had tried this Insert statement earlier on. I just figured out I had to wrap the selection parens ().
Thanks for everyone's help. I'm hoping I can carry this over to the merge for the 3rd table.
This is a nasty problem that keeps coming up. You need to extract the inserted identity values. In SQL Server you can do this using the OUTPUT clause (http://msdn.microsoft.com/en-us/library/ms177564.aspx) with the INSERT "virtual table". This allows you to get all inserted IDs out in one statement.
You can then push the IDs into a temp table and use them to insert the detail records with the appropriate master IDs like this:
INSERT INTO Detail
SELECT * from Staging_Detail
JOIN #MasterIDs on Staging_Detail.MasterID = #MasterIDs.MasterID

sql insert error

This is my Insert Statement
INSERT INTO ProductStore (ProductID, StoreID, CreatedOn)
(SELECT DISTINCT(ProductId), 1, GETDATE() FROM ProductCategory
WHERE EXISTS (SELECT StoreID, EntityID FROM EntityStore
WHERE EntityType = 'Category' AND ProductCategory.CategoryID = EntityStore.EntityID AND StoreID = 1))
I am trying to Insert into table ProductStore, all the Products Which are mapped to Categories that are mapped to Store 1. Column StoreID can definitely have more than one row with the same entry. And I am getting the following error: Violation of Primary Key Constraint...
However, the Following query does work:
INSERT INTO ProductStore (ProductID, StoreID, CreatedOn)
VALUES (2293,1,GETDATE()),(2294,1,GETDATE())
So apparently, the ProductID Column is trying to insert the same one more than once.
Can you see anything wrong with my query?
TIA
I don't see any part of that query that excludes records already in the table.
Take out the INSERT INTO statement and just run the SELECT - you should be able to spot pretty quickly where the duplicates are.
My guess is that you're slightly mistaken about what SELECT DISTINCT actually does, as evidenced by the fact that you have parentheses around the ProductId. SELECT DISTINCT only guarantees the elimination of duplicates when all columns in the select list are the same. It won't guarantee in this case that you only get one row for each ProductId.
select distinct productid is selecting an existing ID and therefor in violation with your primary key constraint.
Why don't you create the primary key using Identity increment? In that case you don't need to worry about the ID itself, it will be generated for you.