Using Set and Between in the same query to populate a table - sql-server

What I am trying to do is populate a row using a counter or some function of sql I am unaware of.
I can use
INSERT INTO EmpSkillsBridge
(EmpIdFK , EmpSkillFK)
Values
(1,1);
This updates one entire record I can even do it in batches of parentheses.
However since I am setting up a the table for the first time and since the data is for test (cough homework cough) reasons. I am trying make it so that the I can create a whole batch of data I have 200 EmpID and 6 different skills. all I want right now is to make the first 25 EmpIdFK and the EmpSkillFK be (1,1)
If i use a where empIdFk < 26 I get an error.
I tried using a loop but being new I got a little lost on how to implement
Then I read I could use the between statement. so my question is can I use a set statement in conjuction with between and make the code work that way?
Set into EmpSkillsBridge
(EmpIdFK , EmpSkillFK)
WHERE (EMPID BETWEEN 1 AND 26)
Values
(1,1);
would this be the best way to go around that?

You can do this:
Insert into EmpSkillsBridge
Select empid, 1
from employees
where empid between 1 and 25;

Something like this should work for you:-
insert into EmpSkillsBridge
(EmpID, EmpSkillsFK)
select empid, 1 from
(
select ROW_NUMBER() over(order by number) empid
from master..spt_values
) v
where empid between 1 and 25

Related

Insert into temp table from SELECT giving strange error

EDIT: I have since been corrected that I need to be doing an update to achieve my intended results. At this point, I'm not able to get the UPDATE statement to do what I want it to, despite my select statement giving me exactly what I want.
begin tran
update #cal1
set calendar_key =
(
SELECT 16801 - 1 + ROW_NUMBER() OVER (
PARTITION BY 1 ORDER BY CalendarDate
) )
FROM #cal1
The results from this give me a repeating 16801 in this column as opposed to going down through the numbers as in my select statement. What am I doing wrong here?
Well, the error seems rather clear and obvious: since you're not specifying the Holiday column in your INSERT statement (in the list of columns you're inserting into), no value is being inserted into Holiday - this is stays NULL.
And it appears from the error message that the Holiday does not allow NULL - you need to explicitly provide a value!
INSERT INTO #cal1 (calendar_key, Holiday)
SELECT
16801 - 1 + ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY CalendarDate) AS count,
-some-value-for-holiday-here-
FROM #cal1
Other than explicitly providing a value, you could also:
Make the Holiday column nullable, so it would be fine with a NULL
Provide a default constraint for Holiday, so that if you don't provide a value, the defined default will be used instead
UPDATE:
Seeing that you say
The problem here is that the other values are as they should be. Is there not a way I can add data to just this one column?
Do you really want to INSERT a new row?? Or would you much rather want to UPDATE an existing row and set just that calendar_key column's value?? In that case, you need an UPDATE statement - not an INSERT ......

Subtract one column from another and get running total SQL Server 2008 R2

I hate to ask a question that it seems like the answer already exists somewhere, but I've been working through various articles over the last couple days (https://www.sqlshack.com/running-running-totals-sql-server/ , Calculate a Running Total in SQL Server, https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-2017 etc.) with minimal progress.
It seems most of the examples given provide a way to join (a self join) or some other WHERE clause to narrow the result set? Anyway, I have a table Location that has columns for PassengersOn and PassengersOff; I would like to be able to calculate the running total of passengers on board at a given time so that my resulting table might look something like this
Which shows a running total (OnBoard) for passengers after each location.
Also, I am aware of the OVER clause available in SQL Server 2012, but unfortunately I'm using 2008 R2.
Again sorry for what may be a duplicate question, but I don't see how I can limit my result set based on a join or WHERE clause since I don't have an incrementing column in my "location" table, instead it uses a guid.
EDIT: here is a sample of the table information
CREATE TABLE Query_8v2 (
[IDStopEvent] NVARCHAR(36),
[LocationID] NVARCHAR(6),
[LocName] NVARCHAR(5),
[PassOn] INT,
[PassOff] INT
);
INSERT INTO Query_8v2 VALUES
(N'f00e6b5b-eb64-4e6b-8b87-0000a539ee36',N'guid1',N'Loc01',0,0),
(N'617cbcae-b467-4adb-b994-00015bca9bb5',N'guid1',N'Loc01',0,59),
(N'215f92bc-8114-4dd0-a1e1-00016e4f0546',N'guid1',N'Loc01',0,42),
(N'e8eaaed5-dc0c-48a9-b39b-0001fc44576e',N'guid1',N'Loc01',0,0),
(N'4c54eef6-11f3-4114-ad9d-0004b1b3849d',N'guid1',N'Loc01',0,0),
(N'a29eb925-8226-4d89-8760-00063d64067a',N'guid1',N'Loc01',69,0),
(N'b16e1b1f-d481-447e-9771-000890fe6999',N'guid1',N'Loc01',0,69),
(N'4f5894ee-a246-4c9d-bc28-0008bc1b3614',N'guid1',N'Loc01',0,44),
(N'52e447cf-f900-4e49-94ca-0008c262a173',N'guid1',N'Loc01',0,0),
(N'f120f646-17f2-4bbb-879d-00091665ec7e',N'guid1',N'Loc01',0,0),
(N'3bbe56e0-c54c-4f3c-9f29-000c914cd724',N'guid1',N'Loc01',32,0),
(N'1ddda821-23f5-43a5-a86c-000d46d4cdc9',N'guid1',N'Loc01',0,0),
(N'b58dac6b-6cac-4bf3-af47-000e67b67582',N'guid1',N'Loc01',0,0),
(N'c9d52156-cc88-4c3c-9409-00103ba9afaa',N'guid1',N'Loc01',0,0),
(N'662d3006-938d-4a66-8999-00104632991b',N'guid1',N'Loc01',0,106),
(N'598d135b-3bdb-4d4b-9464-0010ab22b9eb',N'guid1',N'Loc01',0,0),
(N'c60e2801-efb8-41c3-9dad-00110aae0f2d',N'guid1',N'Loc01',0,0),
(N'72384001-56a3-413c-a847-0011125a5e31',N'guid1',N'Loc01',0,0),
(N'081a9c68-514a-4622-ab0d-00117909d029',N'guid1',N'Loc01',0,0),
(N'afac2c83-ee2e-4b79-8d0b-0011adc313e0',N'guid1',N'Loc01',0,0),
(N'a0f65fe9-79d2-470e-9885-000acccbf82f',N'guid2',N'Loc02',0,0),
(N'bd4371c6-896a-4a4c-9168-000b6e3d2bdd',N'guid2',N'Loc02',0,34),
(N'7c747187-905d-48f5-b9fd-000e233e2986',N'guid2',N'Loc02',21,0),
(N'a3e2773a-2310-4185-9b0c-00013204c0d4',N'guid3',N'Loc03',0,206),
(N'1a8e4c21-0550-411f-91ae-00018234e33d',N'guid3',N'Loc03',323,0),
(N'66ac5d5c-ef97-4041-92cb-0009412a4cec',N'guid3',N'Loc03',0,249),
(N'5b6b2d10-70e4-4953-bf4b-00099ffbc1cd',N'guid3',N'Loc03',183,0),
(N'0107bfcb-9628-42f3-8a4d-000bd42d8cff',N'guid3',N'Loc03',0,400),
(N'f4179bce-399a-417f-bcb1-000fce5ff5b1',N'guid3',N'Loc03',319,0),
(N'f3668d7f-4338-4c15-bb65-0000f5f6af85',N'guid4',N'Loc04',25,32),
(N'dad5af74-a873-46ff-8b61-0002a122850a',N'guid4',N'Loc04',19,75),
(N'e20b705a-6416-4876-aa96-0005e8e25d94',N'guid4',N'Loc04',48,40),
(N'2e3f93d1-65fa-4b13-a8db-0007e6e47b4a',N'guid4',N'Loc04',48,37),
(N'7bc78967-ef77-4fb7-a74d-0008dd88268a',N'guid4',N'Loc04',51,42),
(N'f409014f-189e-4e24-943b-00095acd2e38',N'guid4',N'Loc04',48,71),
(N'e9a6a04d-32da-45e6-a93b-000ae35cd97b',N'guid4',N'Loc04',63,13),
(N'5d719c25-8a20-4cce-85a2-000f6be996ba',N'guid4',N'Loc04',57,69),
(N'5d5a3666-a996-4220-b943-00110f627aee',N'guid4',N'Loc04',27,63),
(N'941880b8-0873-40ee-936b-0001b711fbba',N'guid5',N'Loc05',55,182),
(N'f3f360a1-3767-443e-ac19-000878a505eb',N'guid5',N'Loc05',62,41),
(N'd03d154b-ade6-4c06-af11-000b9fbcb218',N'guid5',N'Loc05',109,86),
(N'7c296996-32a5-46c5-bafd-000e49bf18ba',N'guid5',N'Loc05',126,68),
(N'72424ac3-7b47-44f2-9ffa-0003521bf7c2',N'guid6',N'Loc06',3,3),
(N'abb66bf1-9dab-4f56-a14c-00049b102c9c',N'guid6',N'Loc06',18,38),
(N'2db22514-3a92-4781-9232-000a6d701063',N'guid6',N'Loc06',88,34),
(N'c83239ba-4467-4d8d-9bb6-000b0c802255',N'guid6',N'Loc06',13,13),
(N'32649da2-bd02-44c3-af3a-000d33087fbe',N'guid6',N'Loc06',7,18),
(N'db9f9f3b-f4f0-4300-85c4-000f09011b60',N'guid6',N'Loc06',3,39),
(N'e6aa3c22-489d-4f97-b718-0002071629f1',N'guid7',N'Loc07',55,23),
(N'e648fff9-50ed-42a3-82e4-00027f22287f',N'guid7',N'Loc07',4,28),
(N'7b157c82-1819-4990-8147-0007f4dcaed6',N'guid7',N'Loc07',8,62),
(N'3ffecbf1-bd09-4ef8-b17f-00092211960b',N'guid7',N'Loc07',55,29),
(N'16eab156-126d-440d-a01b-0009a506e922',N'guid7',N'Loc07',3,23),
(N'69af7b49-ce4e-446c-9947-000a42bffa23',N'guid7',N'Loc07',7,8),
(N'd0ba9ab8-80dc-47c9-9f61-000e15b8c049',N'guid7',N'Loc07',3,69),
(N'77749016-19be-4657-b2d5-0005f60f5b5f',N'guid8',N'Loc08',0,163),
(N'7908e6ae-71be-4f3e-aa77-00078b16dbac',N'guid8',N'Loc08',201,0),
(N'10f13d13-9a5c-4ef8-960e-00084b5fa97c',N'guid8',N'Loc08',99,1),
(N'859c00b3-c907-4d90-92de-000e2b7f95d8',N'guid8',N'Loc08',2,167),
(N'e00136e2-e71e-4aed-afbf-00005f66f1b6',N'guid9',N'Loc09',0,299),
(N'ab711e41-e6e3-45b3-ad18-000597d39430',N'guid9',N'Loc09',0,158),
(N'301fada9-f0c1-4afb-aaf2-0005a7d0b3e8',N'guid9',N'Loc09',137,0),
(N'67d1a3f1-547d-495e-98c1-00080e3309b6',N'guid9',N'Loc09',67,0),
(N'a71a4103-dffc-40da-92b8-000a987987a2',N'guid9',N'Loc09',124,0),
(N'a60f9e16-e262-404e-9947-0000732dded4',N'guid10',N'Loc10',0,103),
(N'e4aab4d3-9c58-49fb-a9d7-0001350c9e74',N'guid10',N'Loc10',0,0),
(N'5e8617c7-d2c8-4fb4-b745-0001f8eac18a',N'guid10',N'Loc10',96,0),
(N'1864b5e5-fdda-4f9b-9522-0002e2afee4c',N'guid10',N'Loc10',0,59),
(N'05a93b5f-7776-437c-87b8-000314a9202c',N'guid10',N'Loc10',0,87),
(N'f0d6c884-e906-4aa0-8d01-00034d8d0ea3',N'guid10',N'Loc10',0,0),
(N'0f8c0751-92ed-445e-9bfc-000416967ce6',N'guid10',N'Loc10',0,0),
(N'5733564d-cbeb-4072-bcb5-0004ad90ffc6',N'guid10',N'Loc10',64,0),
(N'bf3209a9-bbb4-4aa2-8463-0006702865a4',N'guid10',N'Loc10',72,0),
(N'289647e7-7de0-482c-8771-00088940f560',N'guid10',N'Loc10',0,0),
(N'1a3cb8cf-dcb1-4441-8ab5-0009bf036b74',N'guid10',N'Loc10',0,0),
(N'6a7a665d-0b4b-41a5-b01a-0009ee84e02b',N'guid10',N'Loc10',73,0),
(N'b75a7e85-f929-4cc6-bf3f-000aaaab33e2',N'guid10',N'Loc10',0,0),
(N'2341b029-55af-41a0-bfa3-000be8e71efe',N'guid10',N'Loc10',0,0),
(N'0bf9396e-99fc-4bf0-9a48-000e90dc0cd2',N'guid10',N'Loc10',0,0),
(N'948b91b3-5928-4eb8-ac1a-000f2d55be2a',N'guid10',N'Loc10',0,0),
(N'50edd548-7a29-40cf-a082-000f5793b5b9',N'guid10',N'Loc10',0,0),
(N'4ad8be92-ce5c-432e-a461-000ff002d0b5',N'guid10',N'Loc10',72,0),
(N'265b0d5b-223b-4da1-9d4f-00107b652ae5',N'guid10',N'Loc10',0,0),
(N'6670c15d-de83-43f4-a5fd-0010d56c574d',N'guid10',N'Loc10',0,0);
I feel like if you were to index the table, you could do this pretty simply. I created a numbered Index via location. If you have the same route of these 10 stops and the data repeats loc1-loc10 over and over, you wouldn't want to use this. You need a primary key, or a date system to make this significantly easier.
SELECT CONVERT(INT, RIGHT(Location, LEN(Location) - 3)) AS ID
,Location
,Passengerson
,PAssengersoff
INTO #IDtable
FROM #table
SELECT ID
,Location
,Passengerson
,Passengersoff
,(SELECT SUM(passengerson-passengersoff)
FROM #IDtable b
WHERE b.ID <= a.ID) AS Total
FROM #IDtable a
ORDER BY ID
this will give a result that looks like this:
Hopefully this helps you in some way.
I don't have access to 2008 R2 but this solution should work from 2005+. It's mid page on the second link provided.
;with MyData as(
select 'loc1' [location], 69 PassengersOn, 0 PassengersOff
union all select 'loc2',61,0
union all select 'loc3',333,0
union all select 'loc4',57,21
union all select 'loc5',49,29
)
SELECT
MyData.*
,RunningTotal.*
FROM MyData
cross apply (select
--SUM(PassengersOn) PassOn
--,SUM(PassengersOff) PassOff
SUM(PassengersOn) - SUM(PassengersOff) as RunningTot
from MyData MyDataApply
where MyDataApply.[location]<= MyData.[location]
) as RunningTotal
ORDER BY MyData.[location]

Field is being updated with same value

I have a table that has a new column, and updating the values that should go in the new column. For simplicity sake I am reducing my example table structure as well as my query. Below is how i want my output to look.
IDNumber NewColumn
1 1
2 1
3 1
4 2
5 2
WITH CTE_Split
AS
(
select
*,ntile(2) over (order by newid()) as Split
from TableA
)
Update a
set NewColumn = a.Split
from CTE_Split a
Now when I do this I get my table and it looks as such
IDNumber NewColumn
1 1
2 1
3 1
4 1
5 1
However when I do the select only I can see that I get the desire output, now I have done this before to split result sets into multiple groups and everything works within the select but now that I need to update the table I am getting this weird result. Not quiet sure what I'm doing wrong or if anyone can provide any sort of feedback.
So after a whole day of frustration I was able to compare this code and table to another that I had already done this process to. The reason that this table was getting updated to all 1s was because turns out that whoever made the table thought this was supposed to be a bit flag. When it reality it should be an int because in this case its actually only two possible values but in others it could be more than two.
Thank you for all your suggestion and help and it should teach me to scope out data types of tables when using the ntile function.
Try updating your table directly rather than updating your CTE. This makes it clearer what your UPDATE statement does.
Here is an example:
WITH CTE_Split AS
(
SELECT
*,
ntile(2) over (order by newid()) as Split
FROM TableA
)
UPDATE a
SET NewColumn = c.Split
FROM
TableA a
INNER JOIN CTE_Split c ON a.IDNumber = c.IDNumber
I assume that what you want to achieve is to group your records into two randomized partitions. This statement seems to do the job.

SQL Server : Row Number without ordering

I want to create a Select statement that ranks the column as is without ordering.
Currently, the table is in the following order:
ITEM_Description1
ITEM_Description2
ITEM_StockingType
ITEM_RevisionNumber
I do not want the results to be numerical in any way, nor depend on the VariableID numbers, but with ROW_Number(), I have to choose something. Does anyone know how I can have the results look like this?
Row| VariableName
---------------------
1 | ITEM_Description1
2 | ITEM_Description2
3 | ITEM_StockingType
4 | ITEM_RevisionNumber
My code for an example is shown below.
SELECT
VariableName,
ROW_NUMBER() OVER (ORDER BY VariableID) AS RowNumber
FROM
SeanVault.dbo.TempVarIDs
Using ORDER BY (SELECT NULL) will give you the results your looking for.
SELECT
VariableName,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM
SeanVault.dbo.TempVarIDs
Your problem seems to be with this sentence:
Currently, the table is in the following order:
No, your table is NOT implicitly ordered!!
Although it might look like this...
The only way to enforce the resultset's sort order is an ORDER BY-clause at the outer most SELECT.
If you want to maintain the sort order of your inserts you can use
a column like ID INT IDENTITY (which will automatically increase a sequence counter)
Using GETDATE() on insert will not solve this, as multiple row inserts might get the same DateTime value.
You do not have to show this in your output of course...
Your table has no inherent order. Even if you get that order a 100 times in a row is no guarantee it will be that order on the 101 time.
You can add an identity column to the table.

SEQUENCE in SQL Server 2008 R2

I need to know if there is any way to have a SEQUENCE or something like that, as we have in Oracle. The idea is to get one number and then use it as a key to save some records in a table. Each time we need to save data in that table, first we get the next number from the sequence and then we use the same to save some records. Is not an IDENTITY column.
For example:
[ID] [SEQUENCE ID] [Code] [Value]
1 1 A 232
2 1 B 454
3 1 C 565
Next time someone needs to add records, the next SEQUENCE ID should be 2, is there any way to do it? the sequence could be a guid for me as well.
As Guillelon points out, the best way to do this in SQL Server is with an identity column.
You can simply define a column as being identity. When a new row is inserted, the identity is automatically incremented.
The difference is that the identity is updated on every row, not just some rows. To be honest, think this is a much better approach. Your example suggests that you are storing both an entity and detail in the same table.
The SequenceId should be the primary identity key in another table. This value can then be used for insertion into this table.
This can be done using multiple ways, Following is what I can think of
Creating a trigger and there by computing the possible value
Adding a computed column along with a function that retrieves the next value of the sequence
Here is an article that presents various solutions
One possible way is to do something like this:
-- Example 1
DECLARE #Var INT
SET #Var = Select Max(ID) + 1 From tbl;
INSERT INTO tbl VALUES (#var,'Record 1')
INSERT INTO tbl VALUES (#var,'Record 2')
INSERT INTO tbl VALUES (#var,'Record 3')
-- Example 2
INSERT INTO #temp VALUES (1,2)
INSERT INTO #temp VALUES (1,2)
INSERT INTO ActualTable (col1, col2, sequence)
SELECT temp.*, (SELECT MAX(ID) + 1 FROM ActualTable)
FROM #temp temp
-- Example 3
DECLARE #var int
INSERT INTO ActualTable (col1, col2, sequence) OUTPUT #var = inserted.sequence VALUES (1, 2, (SELECT MAX(ID) + 1 FROM ActualTable))
The first two examples rely on batch updating. But based on your comment, I have added example 3 which is a single input initially. You can then use the sequence that was inserted to insert the rest of the records. If you have never used an output, please reply in comments and I will expand further.
I would isolate all of the above inside of a transactions.
If you were using SQL Server 2012, you could use the SEQUENCE operator as shown here.
Forgive me if syntax errors, don't have SSMS installed

Resources