SQL Server insert statement to auto increment - sql-server

I have a SQL insert statement like the following:
insert into mytable(ID,Keyindex,KeyValue)
select Id,1,GenreID
from mytable2
Which should populate my table with data like:
id GenreID ColumnB
0006342c-47bc-436a-a23a-3b40360d9a30 16 1
0006342c-47bc-436a-a23a-3b40360d9a30 19 1
00109775-f0f8-463e-8134-f842aac8b5df 12 1
001211e3-9bf8-45ad-8297-7a0a94aaf06e 13 1
0025218a-9624-4f5e-86cc-f1cfe862cd2a 16 1
0025218a-9624-4f5e-86cc-f1cfe862cd2a 11 1
0025218a-9624-4f5e-86cc-f1cfe862cd2a 15 1
The problem is ID,GenreId and ColumnB are primary keys and I am currently inserting a constand value "1" which results in a primary key violation.
How do I insert into the table so that ColumnB gets populated with a value incrementaly if the IDs are the same.
For example:
id GenreID ColumnB
0006342c-47bc-436a-a23a-3b40360d9a30 16 1
0006342c-47bc-436a-a23a-3b40360d9a30 19 2
00109775-f0f8-463e-8134-f842aac8b5df 12 1
001211e3-9bf8-45ad-8297-7a0a94aaf06e 13 1
0025218a-9624-4f5e-86cc-f1cfe862cd2a 16 1
0025218a-9624-4f5e-86cc-f1cfe862cd2a 16 2
0025218a-9624-4f5e-86cc-f1cfe862cd2a 16 3

Your question is a little confusing. In the "for example" section it looks like the genreID for 0025218a-9624-4f5e-86cc-f1cfe862cd2a should be 16,17,19 instead of 16,16,16.
Assuming I understand you correct, though, you can use ROW_NUMBER() OVER partitioned by the id. Something like the following should work :
insert into mytable(ID,Keyindex,KeyValue)
select id, GenreID , ROW_NUMBER() OVER (Partition by id order by id) as ColumnB
from mytable2
order by id,
genereid
Note: you didn't specify version, but this will work in sql 2005+

A dirty hack would be to use id - someNumber or id + someNumber instead of just 1.
What can be accepted if this is a "fire and forget" one time operation.
If you have to check the uniqueness, then a trigger can be the solution.

You could try the ON DUPLICATE option:
insert into mytable(ID,Keyindex,KeyValue)
select Id,1,GenreID
from mytable2
ON DUPLICATE KEY UPDATE Keyindex = Keyindex+1;

Related

How to split Row into multiple column using T-SQL

There are three column,wherever D_ID=13,value_amount holds value for mode of payment and wherever D_ID=10,value_amount holds value for amount.
ID D_ID Value_amount
1 13 2
1 13 2
1 10 1500
1 10 1500
2 13 1
2 13 1
2 10 2000
2 10 2000
Now I have to add two more columns amount and mode_of_payment and result should come like below
ID amount mode_of_payment
1 1500 2
1 1500 2
2 2000 1
2 2000 1
This is too long for a comment.
Simply put, your data is severely flawed. For the example data you've given, you're "ok", because the rows have the same values to the same ID, but what about when they don't? Let's assume, for example, we have data that looks like this:
ID D_ID Value_amount
1 13 1 --1
1 13 2 --2
1 10 1500 --3
1 10 1000 --4
2 13 1 --5
2 13 2 --6
2 10 2000 --7
2 10 3000 --8
I've added a "row number" next to data, for demonstration purposes only.
Here, what row is row "1" related to? Row "3" or row "4"? How do you know? There's no always ascending value in your data, so row "3" could just as easily be row "4". In fact, if we were to order the data using ID ASC, D_ID DESC, Value_amount ASC then rows 3 and 4 would "swap" in order. This could mean that when you attempt a solution, the order in wrong.
Tables aren't stored in any particular order, that are unordered. What determines the order the data is presented in is the ORDER BY clause, and if you don't have a value to define that "order", then that "order" is lost as soon as you INSERT it.
If, however, we add a always ascending value into your data, you can achieve this.
CREATE TABLE dbo.YourTable (UID int IDENTITY,
ID int,
DID int,
Value_amount int);
GO
INSERT INTO dbo.YourTable (ID, DID, Value_amount)
VALUES (1,13,1 ),
(1,13,2 ),
(1,10,1500),
(1,10,1000),
(2,13,1 ),
(2,13,2 ),
(2,10,2000),
(2,10,3000);
GO
WITH RNs AS(
SELECT ID,
DID,
Value_amount,
ROW_NUMBER() OVER (PARTITION BY ID, DID ORDER BY UID ASC) AS RN
FROM dbo.YourTable)
SELECT ID,
MAX(CASE DID WHEN 13 THEN Value_Amount END) AS Amount,
MAX(CASE DID WHEN 10 THEN Value_Amount END) AS PaymentMode
FROM RNs
GROUP BY RN,
ID;
GO
DROP TABLE dbo.YourTable;
Of course, you need to fix your design to implement this, but you need to do that anyway.

How to delete not duplicated rows of 2 tables that only 2 columns of them compare for duplication in SQL Server

I want a stored procedure to create a temptable based on 2 columns of table_A, and then check if there are rows in table_B (with 5 columns) that have these 2 columns like the way they are in table_A. Don't do anything to them a delete rows that are not duplicate.
Something like this:
Create Procedure DeleteExtra
as
Create Table #TempTotalHoney
(
HarvestDate Date,
HoneyType VarChar(50)
)
INSERT INTO #TempTotalHoney
Select HarvestDate, HoneyType
From tHoneyHarvest
Group BY HarvestDate, HoneyType
//until here temptable created as I want, but I don't know how to check
//not duplicated rows, I tried this But it is wrong...
Delete From tHoneyWeight
Where HarvestDate AND HoneyType Not in (select HarvestDate, HoneyType
From #TempTotalHoney)
//must check these tow columns together not separately
If(OBJECT_ID('tempdb..#TempTotalHoney') Is Not Null)
Begin
Drop Table #TempTotalHoney
End
This is the error I get:
Msg 4145, Level 15, State 1, Procedure DeleteExtra, Line 17
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.
Update:
this is #TempTotalHoney that created from table_A
HarvestDate HoneyType
---------------------------------------------------
2017-01-10 Pure
2017-01-10 Semi-Pure
2017-02-03 Pure
2017-02-04 artificial
and
table_B:
RecID HarvestDate HoneyType TotalCombs TotalWeight
----------------------------------------------------------------
1 2017-01-10 Pure 10 22
3 2017-01-10 Semi-Pure 11 24
4 2017-02-03 Pure 22 50
6 2017-02-04 artificial 25 56
8 2017-01-10 Semi-Art 10 18.5
9 2017-02-05 Pure 11 19
I want the RecID 8 and 9 that combination of HarvestDate And HoneyType of them not exists in #TempTotalHoney be deleted.
You can try using below query
DELETE table_B
FROM table_B B
LEFT JOIN #TempTotalHoney A
ON B.HarvestDate = A.HarvestDate
AND B.HoneyType = A.HoneyType
WHERE A.HoneyType is Null;
Hope this would help you out.

i have 4 table in sql and i want the data or all the table where one unique key is matched in four of them

I have a table ratings, bookmark, checkin, food in food table there is a unique key sno and this sno key is used in remaining three tables.
food table
sno name totalrating totalcheckin
1 nitesh 52 45
2 abhishek 4 9
3 divye 42 30
ratings table
sno datakey rated name
1 3 3.0 divye
1 6 4.0 shashank
bookmark table
sno datakey name
1 3 divye
1 6 shashank
Checkin table
sno datakey name
1 2 abhishek
1 6 shashank
I need data where datakey is 3 if not present show null values and data key column not repeated
like
0 1 2 3 4 5 6 7 8 9 10
sno name totalrating totalcheckin sno rated name sno name sno name
3 divye 42 30 1 3.0 divye 1 divye null null
your query should look like this:
SELECT f.sno, f.name, f.totalrating, f.totalcheckin,
r.sno, r.rated, r.name,
b.sno, b.name,
c.sno, c.name
FROM food AS f
LEFT JOIN ratings AS r
ON f.sno = r.datakey
LEFT JOIN bookmark AS b
ON f.sno = b.datakey
LEFT JOIN checkin AS c
ON f.sno = c.datakey
WHERE f.sno = 3
Here is SQL Fiddle to see how it's work.
Also I agree with the guys in the comment which are told you to read something about JOIN syntax. It's pretty and you can start here, or more specific for your problem is LEFT JOIN, that is the begin and good place to start. Also you can see that I use aliases in my query about that read here.
GL!
P.S. (edit) and if you have any question fill free to ask... Also I notice that you have name column in every table, if I understand relation between your table it's not necessary. You should store name only in first table (food) and with simple JOIN from there you can pull that data whenever you need it!

How can I always return Null for a column without updating the column's value in the database?

ID Name tuition num of courses
1 Brandon 4430 6
2 Lisa 2300 3
3 Victoria null 0
4 Jack 3330 4
The type of the tuition column is money, but I need to return return null in my select statement without updating the values in the table.
I tried nullif(tuition is not null), but it didn't work.
How can I return results like those in the table below, without updating the table or modifying the data in database?
ID Name tuition num of courses
1 Brandon null 6
2 Lisa null 3
3 Victoria null 0
4 Jack null 4
If you are returning null for every row, just code the column as:
NULL AS Tuition
Example query:
SELECT Id, Name, NULL as Tuition, NumCourses FROM TheTable
I have created the table and inserted records as you have shown above
It is a self join query.
-- To make sure that the underlying table is not updated run both the queries together.
select TT.Id, TT.Name,
nullif(TT.Tuition, BT.Tuition) as Tuition, TT.NOCs
from tblTuition TT
join tblTuition BT
on TT.Id = Bt.Id
select * from tblTuition
Whenever you need to get value as null then you can use like this,
SELECT NULL AS ABC FROM MYTABLE
So above statement add one ABC column in your select list AS All NULL Values, same thing can be use as getting a Default value e.g. if you want to get 1 then simply use SELECT 1 AS ABC FROM MYTABLE

Select Max from each Subset

I'm banging my head here. I feel pretty stupid because I'm sure I've done something like this before, but can't for the life of me remember how. One of those days I guess >.<
Say I have the following data: ---> and a query which returns this: ---> But I want this:
ID FirstID ID FirstID ID FirstID
-- ------- -- ------- -- -------
1 1 1 1 7 1
2 1 3 3 3 3
3 3 4 4 6 4
4 4 5 5 5 5
5 5
6 4
7 1
Notice that my query returns the records where ID = FirstID, but I want it to return the Max(ID) for each subset of unique FirstID. Sounds simple enough right? That's what I thought, but I keep getting back just record #7. Here's my query (the one that returns the second block of figures above) with some test code to make your life easier. I need this to give me the results in the far right block. It should be noted that this is a self-joining table where FirstID is a foreign key to ID. Thanks :)
declare #MyTable table (ID int, FirstID int)
insert into #MyTable values (1,1),(2,1),(3,3),(4,4),(5,5),(6,4),(7,1)
select ID, FirstID
from #MyTable
where ID = FirstID
Does this work
declare #MyTable table (ID int, FirstID int)
insert into #MyTable values (1,1),(2,1),(3,3),(4,4),(5,5),(6,4),(7,1)
Select FirstID, Max (Id) ID
From #MyTable
Group BY FirstID
Results in
FirstID ID
----------- -----------
1 7
3 3
4 6
5 5
With SQL2005 and later SQL2008 versions the Aggregate functions in SQL Server have been improved
You can use PARTITION BY clause for example with MAX,MIN,SUM,COUNT functions
Please try the following example
select
Distinct FirstID, Max(ID) OVER (PARTITION BY FirstID) MaxID
from #MyTable
You can find an example at http://www.kodyaz.com/t-sql/sql-count-function-with-partition-by-clause.aspx
Upon your comment, I modified the same query just to provide the exact output in order of rows and columns as follows
select Distinct
Max(ID) OVER (PARTITION BY FirstID) ID,
FirstID
from #MyTable
order by FirstID

Resources