I have this following data in my database table (Items):
Above image shows that row 1 and row 2 have same values.
My question is how can I delete the row 2, but because it detects it have same product name, it will add the quantity? For this example row 2 quantity will be added to row 1 quantity. So row 1 quantity have 20 rather than 10, and the database table have only just 1 row.
Sorry for not providing the code.
SQL INSERT Query for the above image:
INSERT INTO [Items] ([Category], [Name], [Quantity], [Price], [Label], [Status]) VALUES (#Category, #Name, #Quantity, #Price, #Label, #Status)
SQL SELECT Query for the above image:
SELECT [Category], [Name], [Quantity], [Price], [Label], [Status], [ImageData] FROM [Items] WHERE [Status] = #Active ORDER BY [Category] ASC;
The #Active Parameter is Active.
T-SQL Create table:
CREATE TABLE [dbo].[Items] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Category] NVARCHAR (50) NULL,
[Name] NVARCHAR (50) NULL,
[Quantity] SMALLINT NULL,
[Price] DECIMAL (18) NULL,
[Label] NVARCHAR (50) NULL,
[Status] NVARCHAR (50) NULL,
[ImageData] VARBINARY (MAX) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
What I want to do:
I want to delete the second row from database, but before that, it will check first and second row if there is same product name, if there is, then it will delete the last row (which is second row in this example), and update the quantity in the first row with what is the quantity in the second row. If first row have 10 quantity, and second row have 20 quantity, then the first row have 30 quantity, and the second row is gone (deleted)
This SQL will group it for you. You are just summing the price and grouping by the rest of the columns.
SELECT
[Category],
[Name],
SUM([Quantity]),
[Price],
[Status],
[ImageData]
FROM [Items] WHERE [Status] = #Active ORDER BY [Category] ASC
GROUP BY
[Category],
[Name],
[Price],
[Status],
[ImageData]
Ideally you should have a "ProductID" column in this table so that you can group by this instead of relying on the procuct Name being unique.
Here is the update that will update the quantity of the first record with the sum of its quantity plus the quantities in any records with the same category and name that come after it, and then the delete statement that will delete those later records, while leaving your firstone intact:
update items i1
inner join items i2 on i1.category = i2.category and i1.name = i2.name
and i1.id < i2.id
set i1.quantity = i1.quantity + i2.quantity
delete i1 from items i1
inner join items i2 on i1.id > i2.id and
i1.category = i2.category and i1.name = i2.name
Related
On a project where we have SQL tables called Products and Conditions, we want to determine which product belongs to which most matching condition, because a product can belong to multiple conditions.
Is there a way to do this in C# or SQL?
Below you can find a shorted version of the tables with the properties that we want to match on:
CREATE TABLE Products
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY(1,1),
[Property1] SMALLINT NULL,
[Property2] SMALLINT NULL,
[Property3] NVARCHAR(20) NULL,
[Property4] NVARCHAR(20) NULL
)
CREATE TABLE Conditions
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY(1,1),
[Property1] SMALLINT NULL,
[Property2] SMALLINT NULL,
[Property3] NVARCHAR(20) NULL,
[Property4] NVARCHAR(20) NULL
)
As a result we want for each product the conditions and sorted by most matching score based on the 4 properties.
Because we have 4 properties, the resulting score could be 0 / 25 / 50 / 75 / 100.
In sql you can join the two tables on matching properties and use iif method to compute the total score and order the results by the total score like below :
Select * from (
Select p.*, c.*,
iif([Property1] = p.[Property1],25,0) +
iif([Property2] = p.[Property2],25,0) +
iif([Property3] = p.[Property3],25,0) +
iif([Property4] = p.[Property4],25,0) [TotalScore]
from Products p inner join Conditions c
on c.[Property1] = p.[Property1] or
c.[Property2] = p.[Property2] or
c.[Property3] = p.[Property3] or
c.[Property4] = p.[Property4]) q
order by TotalScore desc
I have a table Invoices
Structure of Invoices
CREATE TABLE Invoices (
Id int NOT NULL IDENTITY (1, 1),
Depot nvarchar(100) NOT NULL,
InvoiceNo nvarchar(100) NOT NULL,
InvoiceDate datetime NOT NULL,
Licencee nvarchar(255) NOT NULL,
Outlet nvarchar(1024) NOT NULL,
SerialNo int NOT NULL,
ProductName nvarchar(500) NOT NULL,
Size int NOT NULL,
[Case] int NOT NULL,
BeverageSegment nvarchar(100),
/* Keys */
PRIMARY KEY (Id)
)
GO
CREATE INDEX Invoices_BeverageSegment
ON Invoices
(BeverageSegment)
GO
CREATE INDEX Invoices_InvoiceId
ON Invoices
(InvoiceNo)
GO
I have to query for Total Sales for a particular Depot, for a Product on Date, i have approx 1,35,850 in the Table, the Query is taking 47 minute.
I do not have much expertise in database system, i have checked for Query Optimization for SqlCe but none of them helps in this condition.
My query :
SELECT
Depot,
InvoiceDate,
ProductName,
Size,
SUM([Case]) as Cases
FROM Invoices
GROUP BY
Depot,
InvoiceDate,
ProductName,
Size
Creating a non clustered index on all the four columns Depot, InvoiceDate, ProductName, Size will increase the performance.
Create NonClustered Index Index_Name
on
Invoices ( Depot, InvoiceDate, ProductName, Size)
I need a way to get column definition from query result. Right now I'm using SQL Server 2012.
Here is the example scenario, I have two tables which are Event and Attendant whose definitions are below :
CREATE TABLE [dbo].[Event] (
[Id] INT NOT NULL,
[Name] NVARCHAR (50) NULL,
[Description] NVARCHAR (50) NULL,
[StartDate] DATETIME NULL,
[EndDate] DATETIME NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Attendant] (
[Id] INT NOT NULL,
[EventId] INT NOT NULL,
[Name] NVARCHAR (50) NULL,
[Company] NVARCHAR (50) NULL
PRIMARY KEY CLUSTERED ([Id] ASC)
);
And then I have query such as :
SELECT Event.Name as EventName, Attendant.Name as GuestName
FROM Event
INNER JOIN Attendant ON Event.Id = Attendant.EventId
How Can I get the column definition for above example query result? My objective is to generate poco class to represent each record of any query result using c#.
you can use sp_columns sproc to retrieve information about the column definition of a specified table ... like this:
exec sp_columns Attendant
Use sp_columns, it returns column information for the specified objects(tables).
Refer this link for details.
select * from information_schema.columns where table_name = '<tablename>'
Hi I have the following stored procedure:
create procedure dbo.AddNewUser
(
#uName nvarchar(20),
#pass nvarchar(20),
#fName nvarchar(20),
#lName nvarchar(20)
)
AS
insert into [Users] (Username, Password, Firstname, Lastname)
values (#uName, #pass, #fName, #lName)
This is the code for my table:
CREATE TABLE [dbo].[Users] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Username] NCHAR (20) NOT NULL,
[Password] NCHAR (20) NOT NULL,
[Firstname] NCHAR (20) NOT NULL,
[Lastname] NCHAR (20) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
My windows forms program currently has 4 textboxes and 1 button. I am trying to insert the text from the textboxes into my database. This is the code from my click event:
DatabaseConnectionDataContext dc = new DatabaseConnectionDataContext();
dc.AddNewUser(tbUsername.Text, tbPassword.Text, tbFirstname.Text, tbLastname.Text);
dc.SubmitChanges();
When I start the program, enter some data in the textboxes and click the button the data from the textboxes is inserted into the table, but when i start the program again and enter some data into the textboxes, the new data is inserted on the first line instead creating a new line and the old data is erased. Anyone can suggest why is this happening?
You are missing the check if user exists, normally you would do that by id.
using (var dc = new DatabaseConnectionDataContext()){
if (dc.Users.Any(o => o.Username== tbUsername.Text && o.Password == tbPassword.Text ...){
...
}else{dc.AddNewUser(tbUsername.Text, tbPassword.Text, tbFirstname.Text, tbLastname.Text);}
dc.SubmitChanges();
}
EDIT: Having read comment from StefanoGermani
Are you running in memory ravenDb by any chance?
This is what I want to achieve:
I want to query my db to return a list of entities
Randomize the list
Store the IDS of items received for future queries
Run a new query on the same table where the IDs are in the list that I have stored
Order by the list that I have stored.
I have managed to achieve step 1, 2, 3, 4 already but step 5 is difficult. Can anyone help me with a query like so:
SELECT *
FROM table_name
WHERE id IN (1,2,3,4....)
ORDER BY (1,2,3,4....)
Thanks in advance
Try
SELECT table_name.*
FROM crazy_sorted_table
LEFT JOIN
table_name ON crazy_sorted_table.ID=table_name.ID
A normal join (equi join) should do the trick , here is sample approach i tested:
/**crazyOrder filled 100 rows with random value from 1-250 in Id**/
CREATE TABLE [dbo].[crazyOrder] (
[Id] INT NOT NULL,
[Area] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
/**Normal order is filled with value from 1-100 sequentially in id**/
CREATE TABLE [dbo].[normalOrder] (
[Id] INT NOT NULL,
[Name] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
create table #tempOrder
(id int)
insert into #tempOrder
Select top 10 Id
from crazyOrder
order by NewID()
go
Select n.*
from normalOrder n
join #tempOrder t
on t.id = n.id
I was able to retrieve the rows in the same order as in the temp table (i used a data generator for the values)