Sql Select 0 1 0 1 sequence from database table - sql

I need to fetch output from given below table in
0
1
0
1
sequence .All other data at the end of table.
create table #Temp
(
EventID INT IDENTITY(1, 1) primary key ,
Value bit
)
INSERT INTO #Temp(Value) Values
(0),(1)
,(0),(0)
,(0),(0)
,(0),(0)
,(1),(1)
,(1),(1)
,(1),(0)
,(0),(0)
,(1),(1)
,(0),(1)

This is probably what you want:
select *
from #Temp
order by row_number() over (partition by Value order by EventID), Value

Related

How to get the each record with some condition

I have following data:
DECLARE #temp TABLE (
ID int
,sn varchar(200)
,comment varchar(2000)
,rownumber int
)
insert into #temp values(1,'sn1',NULL,1)
insert into #temp values(2,'sn1','aaa',2)
insert into #temp values(3,'sn1','bbb',3)
insert into #temp values(4,'sn1',NULL,4)
insert into #temp values(5,'sn2',NULL,1)
insert into #temp values(6,'sn2',NULL,2)
insert into #temp values(7,'sn2',NULL,3)
select * from #temp
And I want to output like this:
2 sn1 aaa 2
5 sn2 NULL 1
same sn, if comment have value, get this lower rownumber's record. For sn1, have two records with comment value, so here, get the the record with rownumber=2
If comment doesn't have value, get the lower rownumber's record. For sn2, get the record with rownumber=1
May I know how to write this SQL?
This is a prioritization query. I think row_number() is the simplest method:
select t.*
from (select t.*,
row_number() over (partition by sn
order by (case when comment is not null then 1 else 2 end),
rownumber
) as seqnum
from #temp t
) t
where seqnum = 1;
Here is a db<>fiddle.

select the value from the nth position above

I need to calculate something by getting the corresponding value from a field (let's say abc256) to which i must subtract the value from the same column but 249 rows above (let's say abc7) and then multiply it by 100 into a new column in a temporary table (only for displayin the output).
How to count from the current value 249 fields above?
I already ordered the list as it should be by 2 columns asc.
So the query which orders my list looks like:
select [rN] ,[rD],[r],[rId]
from [someName].[dbo].[some_table]
where rN like '%bla%'
and rD >= 'yyy-mm-dd'
EDIT: order by rD asc, rID asc
a pseudocode of what i need is:
[(case when rN like 'something' then newSomething = (r.value - r.count(249).value))*100) as newSomething)]
FROM [someName].[dbo].[some_table]
then i tried
select [rN] ,[rD],[r],[rId]
from select (ROW_NUMBER() over (order by key ASC) AS rownumber,
r)
from
[someName].[dbo].[some_table]
where rownumber = r -249
where rN like '%bla%'
and rD >= 'yyy-mm-dd'
I should mention that i need to to a repetitive process of this (after each 249 rows i am calculating using the current value - the value from 249 rows above). And i will have 12 cases for rN like 'something1' ...'something12'
How to get this to work?
Thanks
You will have to adapt this to your specific needs, but whenever I am posed with the "Compare a column to the one nth one before it" problem, I revert to CTE expressions and then do a self-join. I've thrown together a quick example to get you started. I hope you find it useful.
-- DROP TABLE IF EXISTS
IF OBJECT_ID('Table_1') IS NOT NULL
DROP TABLE Table_1
GO
-- CREATE A TABLE FOR TESTING
CREATE TABLE [dbo].[Table_1](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Num1] [int] NULL,
[Num2] [int] NULL
) ON [PRIMARY]
GO
-- FILL THE TABLE WITH VALUES
DECLARE #cnt INT; SET #cnt = 0
WHILE #cnt <=10000
BEGIN
SET #cnt = #cnt + 1
INSERT INTO Table_1 (Num1, Num2) VALUES (#cnt, #cnt * 1000)
END
GO
-- DO THE SELECT
; With RowedTables AS (
SELECT
ROW_NUMBER() OVER (ORDER BY Id ASC) As R,
T1.*
FROM Table_1 T1)
SELECT
RT1.Num1 - RT2.Num1 AS SomeMath,
RT1.*,
RT2.*
FROM RowedTables RT1 JOIN RowedTables RT2 ON RT1.R = RT2.R - 10

SQL Server 2012 Sequence Object

Here is my sample table, the primary key is a composite key of Akey+Bkey
Akey Bkey ItemSequence
---- ---- ------------
1 1 1
1 5 2
1 7 3
2 7 1
3 2 1
3 3 2
Akey is generated from a SQL 2012 Sequence object ASequence. In most cases I insert one row at a time and when necessary I call NEXT VALUE FOR ASequence. However I need to do an insert from a statement like:
SELECT DENSE_RANK() OVER ( ORDER BY Something) as AKey,
Bkey, Sequence
FROM TABLEB
The OVER clause of the NEXT VALUE does not work this way as I need to be able to insert records as a SET but only increment the Sequence once per DENSE_RANK set.
So we have the ALTER SEQUENCE command and with this I am able to set the sequence to what I want. The caveat to this is that it must be a constant and will not accept a variable. My workaround to this was:
DECLARE #startingID INT
DECLARE #sql VARCHAR(MAX)
DECLARE #newSeed INT
SET #startingID = NEXT VALUE FOR ASequence
INSERT TABLEA
SELECT DENSE_RANK() OVER ( ORDER BY Something) + #startingID as AKey,
Bkey, Sequence
FROM TABLEB
SELECT #newSeed = MAX(Akey) FROM TABLEA
SET #sql = ‘ALTER SEQUENCE ASEQUENCE RESTART WITH ‘ + cast(#newSeed+1 as varchar(10))
EXEC(#sql)
Seems terrible to have DML statements in Dynamic SQL like this. Is there a better way to do this?
This should do it:
INSERT TABLEA
SELECT NEXT VALUE FOR ASequence OVER(ORDER BY Something) as AKey,
Bkey, Seq
FROM TABLEB
Or, how about this:
CREATE TABLEA
(
GroupID INT,
AKey INT,
BKey INT,
ItemSequence INT,
CONSTRAINT PK_TABLEA PRIMARY KEY CLUSTERED
(
GroupID,
AKey,
BKey
)
)
DECLARE #GroupID INT
SET #GroupID = NEXT VALUE FOR ASequence
INSERT TABLEA
SELECT #GroupID, DENSE_RANK() OVER ( ORDER BY Something) as AKey,
Bkey, Sequence
FROM TABLEB
and if you need the value of AKey as it is in your example, you can do GroupID+AKey here.

How to increment a second primary key column in a table automatically when a new entry is added for the first primary key column

I am trying to find a way to increment a second primary key column in a table automatically when a new entry is added for the first primary key column. I suppose an example would be best here so here goes.
Suppose I have a table:
CREATE TABLE T
(
SecNum INT NOT NULL,
EntryID INT NOT NULL,
Value FLOAT,
) CONSTRAINT [PK_T] PRIMARY KEY CLUSTERED
(
[SecNum] ASC,
[EntryID] ASC
)
I would run the following statement:
INSERT INTO T (SecNum, Value) VALUES (0, 10)
My table should look like:
SECNUM | ENTRYID | VALUE
-------------------------
0 0 10
I would run the following statement:
INSERT INTO T (SecNum, Value) VALUES (0, 10)
My table should look like:
SECNUM | ENTRYID | VALUE
-------------------------
0 0 10
0 1 10
I would run the following statement:
INSERT INTO T (SecNum, Value) VALUES (1, 20)
My table should look like:
SECNUM | ENTRYID | VALUE
-------------------------
0 0 10
0 1 10
1 0 20
This is possible using an INSTEAD OF trigger:
CREATE TRIGGER TriggerName
ON T
INSTEAD OF INSERT
AS
-- THIS TOP BIT IS OPTIONAL, IT WILL ALLOW ENTRY ID TO BE OVERRIDDEN IF
-- IT IS SUPPLIED TO THE INSERT AND WILL NOT VIOLATE THE PRIMARY KEY
IF NOT EXISTS
( SELECT 1
FROM T
INNER JOIN inserted i
ON i.SecNum = T.secNum
AND i.EntryID = T.EntryID
UNION
SELECT 1
FROM inserted
WHERE EntryID IS NULL
)
BEGIN
INSERT T (SecNum, EntryID, Value)
SELECT SecNum, EntryID, Value
FROM inserted
END
ELSE
-- IF OVERRIDE ABILITY IS NOT REQUIRED JUST USE THE BELOW INSERT
BEGIN
INSERT T (SecNum, EntryID, Value)
SELECT i.SecNum, COALESCE(LastID, 0), i.Value
FROM inserted I
LEFT JOIN
( SELECT SecNum, MAX(T.EntryID) + 1 [LastID]
FROM T
GROUP BY SecNum
) T
ON T.SecNum = i.SecNum
END
Example here
HOWEVER this is not very elegant. It could be worth asking is it really necessary? Could you get away with using a surrogate primary key, and use ROW_NUMBER() to create Entry ID's on the fly?
How about something like this:
INSERT INTO T (SecNum, Value, EntryId)
SELECT 0, 10, count(*)
FROM T WHERE SecNum = 0
It is not the cleanest solution and will perform pretty poorly too. But it should get the job done.
This is how to do it without storing the value in the table (I'm not sure why you want to store it)
TABLE
DECLARE #T TABLE
(
SecNum INT NOT NULL,
EntryID INT,
Value FLOAT
)
DATA
INSERT INTO #T
( SecNum, Value )
VALUES ( 0, 10 )
INSERT INTO #T
( SecNum, Value )
VALUES ( 0, 10 )
INSERT INTO #T
( SecNum, Value )
VALUES ( 1, 20 )
QUERY
SELECT SecNum,
ROW_NUMBER() OVER ( PARTITION BY value ORDER BY Value ) - 1 AS EntryID,
Value
FROM #T
RESULT
SecNum EntryID Value
0 0 10
0 1 10
1 0 20
If the EntryID changes with SecNum AND Value use this query:
SELECT SecNum,
ROW_NUMBER() OVER ( PARTITION BY Value,SecNum ORDER BY Value, SecNum ) - 1 AS EntryID,
Value
FROM #t
RESULT 2
SecNum EntryID Value
0 0 10
0 1 10
1 0 10
1 0 20
Your problem can be solved by using an instead of insert trigger
create trigger Trigger1 on T INSTEAD OF INSERT
as
begin
insert into T(SecNum,EntryID,Value)
select SecNum,
(select count(*) from T where SecNum = i.SecNum) as EntryID,
value
from inserted i
end

Struggling to count and order by a column by reference in T-SQL database

I'm not sure if I'm writing the following SQL statement correctly? (Using T-SQL)
I have two tables:
Table 1: [dbo].[t_Orgnzs]
[id] = INT
[nm] = NVARCHAR(256)
Table 2: [dbo].[t_Usrs]
[id] = INT
[ds] = NVARCHAR(256)
[oid] = INT (referenced [dbo].[t_Orgnzs].[id])
I need to select elements from Table 2, ordered by the [oid] column ascending from 1 to 16, but the catch is that the [oid] references a string in the Table 1, that I actually need to return as a result.
So for say, if tables were laid out like so:
Table 1:
id nm
1 Name 1
2 Name 2
3 Name 3
4 Name 4
And Table 2:
id ds oid
1 A 2
2 B 4
3 C 1
The resulting query must return:
3 C Name 1
1 A Name 2
2 B Name 4
So here's the SQL I'm using:
WITH ctx AS (
SELECT [id],
[ds],
(SELECT [nm] FROM [dbo].[t_Orgnzs] WHERE [id]=[dbo].[t_Usrs].[oid]) AS organizName,
ROW_NUMBER() OVER (ORDER BY organizName ASC) AS rowNum
FROM [dbo].[t_Usrs]
)
SELECT [id], [ds], organizName
FROM ctx
WHERE rowNum>=1 AND rowNum<=16;
And I'm getting an error: "Invalid column name 'organizName'."
I do not understand the meaning of use ROW_NUMBER() in your case. Why?
CREATE TABLE [t_Orgnzs] ([id] int PRIMARY KEY, [nm] NVARCHAR(256))
GO
CREATE TABLE [t_Usrs] ([id] int, [ds] NVARCHAR(256), [oid] int FOREIGN KEY REFERENCES [t_Orgnzs]([id]))
GO
INSERT [t_Orgnzs] VALUES (1,'Name_1')
INSERT [t_Orgnzs] VALUES (2,'Name_2')
INSERT [t_Orgnzs] VALUES (3,'Name_3')
INSERT [t_Orgnzs] VALUES (4,'Name_4')
GO
INSERT [t_Usrs] VALUES (1,'A',2)
INSERT [t_Usrs] VALUES (2,'B',4)
INSERT [t_Usrs] VALUES (3,'C',1)
GO
SELECT *
FROM [t_Orgnzs]
INNER JOIN [t_Usrs] ON [t_Orgnzs].[id]=[t_Usrs].[oid]
ORDER BY [oid]
How about this one
select id, ds, nm
from
(
select ROW_NUMBER() OVER (ORDER BY o.nm ASC) AS rowNum, u.id, u.ds, o.nm
from t_Usrs u inner join t_Orgnzs o on (u.oid = o.id)
) t
WHERE rowNum>=1 AND rowNum<=16;
SELECT TOP 16 * FROM [t_Orgnzs]
INNER JOIN [t_Usrs]
ON [t_Orgnzs].[id] = [t_Usrs].[oid]
ORDER BY [oid]