Create 2 pair unique id data rows - sql-server

I want create 2 data rows with 1 same findable unique id to each one by 1 query
2 difference is side column {1 buyer} {0 seller } and userId column {userID's}
id userId side price qty pairId
1 6 0 60 10 1
2 9 1 60 10 1
trying to visualize result table:
In SQL Server I tried SCOPE_IDENTITY()
insert into [dbo].[deals] (side, price, qty,pairId)
values (1, 60, 10 ,SCOPE_IDENTITY()),
(0, 60, 10 ,SCOPE_IDENTITY()),
create table command:
CREATE TABLE [demonstration].[dbo].[Deals](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[userId] [int] NULL,
[side] [smallint] NULL,
[qty] [decimal](18, 4) NULL,
[price] [decimal](18, 4) NULL,
[pairId] [bigint] NULL
) ON [PRIMARY]
GO

Add an IDENTITY column to deals table(or alter one column to identity) then use your query:
insert into [dbo].[deals] (side, price, qty,pairId)
values (1, 60, 10 ,IDENT_CURRENT('deals')+1),
(0, 60, 10 ,IDENT_CURRENT('deals')+1)
added +1

Related

Using Goup By in Procedure - SQLServer

I have two tables in my database:
/* Create class table */
CREATE TABLE Class
(
CId INT NOT NULL,
ClassName VARCHAR (50) NOT NULL,
ClassDescription VARCHAR (MAX) NULL,
ClassStatus VARCHAR (50) NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
Degree VARCHAR (50) NOT NULL,
TeacherName VARCHAR (50) NOT NULL,
ClassTopic VARCHAR (50) NOT NULL,
CONSTRAINT CHK_Dates CHECK (EndDate > StartDate),
CONSTRAINT CHK_Status CHECK (ClassStatus = 'Active' Or ClassStatus = 'NAct' Or ClassStatus = 'Archive'),
CONSTRAINT CHK_Degree CHECK (Degree = '1st' Or
Degree = '2nd' Or
Degree = '3rd' Or
Degree = '4th' Or
Degree = '5th' Or
Degree = '6th' Or
Degree = '7th' Or
Degree = '8th' Or
Degree = '9th' Or
Degree = '10th' Or
Degree = '11th' Or
Degree = '12th'),
CONSTRAINT CHK_Topic CHECK (ClassTopic = 'Mth' Or
ClassTopic = 'Ph' Or
ClassTopic = 'Ch' Or
ClassTopic = 'Bio' Or
ClassTopic = 'Fr' Or
ClassTopic = 'En' Or
ClassTopic = 'Arb' Or
ClassTopic = 'Rgs'),
PRIMARY KEY (CId)
);
/* Create Student table*/
CREATE TABLE Student
(
_SId INT NOT NULL,
UserName VARCHAR (50) NOT NULL,
Bdate DATE NOT NULL,
SPassword VARCHAR (50) NOT NULL,
SName VARCHAR (50) NOT NULL,
SLastName VARCHAR (50) NOT NULL,
NationalCode VARCHAR (10) NOT NULL,
Email VARCHAR (MAX) NULL,
StudentClass INT NOT NULL,
HomePhone VARCHAR (8) NOT NULL,
CONSTRAINT CHK_Email CHECK (Email like '%_#__%.__%'),
PRIMARY KEY (_SId),
FOREIGN KEY (StudentClass) REFERENCES Class (CId) ON DELETE CASCADE
);
ALTER TABLE Student
ADD CONSTRAINT New_CHK_NCode CHECK (NationalCode LIKE '%[0-9]%');
ALTER TABLE Student
ADD CONSTRAINT New_CHK_Phone CHECK (HomePhone LIKE '%[0-9]%');
I have inserted the below records in each of them:
USE School
/* Inserting data into tables */
INSERT INTO dbo.Class (CId, ClassName, ClassDescription, ClassStatus, StartDate, EndDate, Degree, TeacherName, ClassTopic)
VALUES (1, 'aaa', NULL, 'Active', '20020907', '20030907', '1st','Eetemadi', 'Mth'),
(2, 'bbb', NULL, 'Active', '20020907', '20030907', '1st','Rahmani', 'Ph'),
(3, 'ccc', NULL, 'Active', '20020907', '20030907', '2nd','Entezari', 'Ch'),
(4, 'ddd', NULL, 'Active', '20020907', '20030907', '2nd','Beytollahi', 'Bio'),
(5, 'eee', NULL, 'Active', '20020907', '20030907', '3rd','Zahirpour', 'Fr');
INSERT INTO dbo.Student (_SId, UserName, Bdate, SPassword, SName, SLastName, NationalCode, Email, StudentClass, HomePhone)
VALUES (1, 'aaa', '20020807', '1234', 'maryam', 'vahdati', '1234567890', 'mar#gmail.com', 1, '12345678'),
(2, 'bbb', '20020707', '4321', 'marjan', 'vahdati', '1234578906', 'marj#gmail.com', 1, '12345678'),
(3, 'ccc', '20020607', '1342', 'masomeh', 'vahdati', '1234567809', 'mas#gmail.com', 2, '12345678'),
(4, 'ddd', '20020507', '1243', 'mohammad', 'vahdati', '1234568907', 'moh#gmail.com', 2, '12345678'),
(5, 'eee', '20020407', '1342', 'mahmod', 'vahdati', '1245678903', 'mah#gmail.com', 3, '12345678');
Now I have to write a query in a Procedure to group classes based on degrees, show the number of students in every grade, and also the total number of classes.
I have written the below query:
ALTER PROCEDURE dbo.FirstReport
AS
BEGIN
Select Degree, COUNT(Degree) as numberOfClasses, COUNT(StudentClass) as numberOfStudents
FROM Class C left outer join Student S ON C.CId = S.StudentClass
GROUP BY Degree
UNION ALL
SELECT 'SUM' Degree, COUNT(Degree), COUNT(StudentClass)
FROM Class C join Student S ON C.CId = S.StudentClass;
END
The output is:
| Degree| numberOfClasses | numberOfStudents|
|:-----------------------------------------:|
|1st | 4 | 4 |
|2nd | 2 | 1 |
|3rd | 1 | 0 |
|SUM | 5 | 5 |
But the numberOfClasses must be 2 when the Degree is 1st.
I do not know how to make it correct. I will be grateful for your help.
As I mentioned in the comments, you have a many to one join here, and thus the COUNT you get is correct, due said one to many join; you have 2 rows that each join to 2 other rows and 2 * (1 * 2) = 4.
Instead, use a DISTINCT on your first COUNT on the ID column. Also, there's no need for a UNION ALL; you can use GROUPING SETS or ROLLUP to get the "grand total" row:
SELECT ISNULL(C.Degree,'SUM') AS Degree,
COUNT(DISTINCT C.CId) AS NumberOfClasses,
COUNT(S.StudentClass) AS NumberOfStudents
FROM dbo.Class C
LEFT OUTER JOIN dbo.Student S ON C.CId = S.StudentClass
GROUP BY GROUPING SETS(Degree,());

Check in and check out time in SQL

simple data of table
My table is:
SELECT TOP (1000)
[ID]
,[UserName]
,[CheckTime]
,[Checktype]
,[CheckinLocation]
,[lat]
,[lng]
FROM
[dbo].[CheckTime]
INSERT INTO [dbo].[CheckTime] ([UserName], [CheckTime], [Checktype],[CheckinLocation], [lat], [lng])
VALUES (<UserName, nchar(10),>
,<CheckTime, datetime,>
,<Checktype, nvarchar(50),>
,<CheckinLocation, nvarchar(50),>
,<lat, float,>
,<lng, float,>)
GO
Create table script:
CREATE TABLE [dbo].[CheckTime]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nchar](10) NULL,
[CheckTime] [datetime] NULL,
[Checktype] [nvarchar](50) NULL,
[CheckinLocation] [nvarchar](50) NULL,
[lat] [float] NULL,
[lng] [float] NULL,
CONSTRAINT [PK_CheckTime]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
I need to select each distinct home holding the maximum value of datetime.
max CheckTime as check out
min CheckTime as check in
I need a result like this:
id | Username | check in | check out
---+----------+-------------------+-------------------
1 | 10 | 2017-1-2 08:02:05 | 2017-1-2 10:02:05
1 | 12 | 2017-1-2 08:02:05 | 2017-1-2 10:02:05
1 | 12 | 2017-1-3 08:02:05 | 2017-1-3 10:02:05
1 | 10 | 2017-1-3 08:02:05 | 2017-1-3 10:02:05
I have tried:
You can try the following query.
Select Username
, Cast(CheckTime as Date) as CheckDate
, min(CheckTime) as [check in]
, max(CheckTime) as check out
From CheckInTable
Group by id, Username, Cast(CheckTime as Date)

How could I make a series of joins work with max value when aggregates do not work in them?

I'm looking only to get classification ids which are between the valid year range in classification. I'm using left joins because NULLs should be permitted.
I have tables:
CREATE TABLE classifications (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[classification_code] [varchar](20) NOT NULL,
[description] [varchar](255) NULL,
[valid_from] [int] NULL,
[valid_to] [int] NULL
--Rest of constraints...
)
insert into classifications (classification_code, description, valid_from, valid_to)
values ('05012','Classification Number 1',2007,2012),
('05012','Classification Number 1',2013,2016),
('05012','Classification Number 1',2017,2020).
('12043','Classification Number 2',2007,2010),
('12043','Classification Number 2',2011,2020),
('12345','Classification Number 3',2013,2015),
('12345','Classification Number 3',2016,2020),
('54321','Classification Number 4',2007,2009),
('54321','Classification Number 4',2010,2013),
('54321','Classification Number 4',2014,2020)
CREATE TABLE comm_info_a (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[comm_code] [nchar](10) NOT NULL, /*should be unique*/
[classification_code] [nchar](6) NULL,
[thing] [nchar](6) NULL
--Rest of constraints...
)
insert into comm_info_a (comm_code, classification_code)
values ('0100100000','54321'),
('8090010000','05012'),
('5002310010','12043'),
('0987654321','54321')
CREATE TABLE comm_info_b (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[comm_code] [nchar](10) NOT NULL, /*should be unique*/
[classification_code] [nchar](6) NULL
--Rest of constraints...
)
insert into comm_info_b (comm_code, classification_code)
values ('0100100000','12043'),
('8090010000','00000'),
('5002310010','05012'),
('1234567890','12345')
CREATE TABLE transactions (
[comm_code] [varchar](50) NULL,
[year] [varchar](255) NULL
--Rest of constraints...
)
insert into transactions (comm_code, year) values
('0100100000', 2013),
('0100100000', 2015),
('0100100000', 2017),
('8090010000', 2009),
('8090010000', 2010),
('8090010000', 2011),
('8090010000', 2015),
('8090010000', 2017),
('8090010000', 2018),
('5002310010', 2008),
('5002310010', 2014),
And finally:
CREATE TABLE comm (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[comm_code] [varchar](20) NULL, /*should be unique*/
[fk_classification_id_a] [bigint] NULL,
[fk_classification_id_b] [bigint] NULL
--Rest of constraints...
)
I am working on a query to insert comms from transactions, and comms should have unique comm_code
The query is as follows:
INSERT INTO comm
(comm_code,
fk_classification_id_a,
fk_classification_id_b)
SELECT comm_code,
ca.id,
cb.id,
MAX(year)
FROM transactions t
LEFT JOIN comm_info_a mia ON mia.comm_code=t.comm_code
LEFT JOIN comm_info_b mib ON mib.comm_code=t.comm_code
--these next two joins obviously do not work so I'm looking for something like it. Treat them as 'pseudo-code'
LEFT JOIN classifications ca ON ca.classification_code=mia.classification_code AND
MAX(t.year) BETWEEN ca.valid_from AND ca.valid_to
LEFT JOIN classifications cb ON cb.classification_code=mib.classification_code AND
MAX(t.year) BETWEEN cb.valid_from AND cb.valid_to
-- end of the two joins
WHERE NOT EXISTS
(SELECT DISTINCT comm_code FROM comm)
GROUP BY
t.comm_code
t.classification_code
So in the end I'm looking to get something like this as a result:
comm_code | fk_classification_id_a | fk_classification_id_b
-----------|------------------------|-----------------------
0100100000 | 5 | 10
8090010000 | 3 | NULL
5002310010 | 5 | 2
Please note that the comm_code is unique in this table!! Therefore: i want the comms on the newest transactions (thus the aggegate max year), and they should have the ids of the classification that the transaction year is in.
The real query is much more complex and longer but this pretty much covers all bases. Take a look into what is commented. I understand that it should be doable with a sub query of some sort, and I've tried, but so far I haven't found a way to pass aggregates to subqueries.
How could I tackle this problem?
Revised answer uses a common table expression to calculate the maximum year per comm_code and to exclude the comm_codes not wanted in the final result. After that the joins to the classification tables are straight forward as we have the comm_max_year value on each row to use in the joins.
with transCTE as (
select
t.*
, max(t.year) over(partition by comm_code) comm_max_year
from transactions t
left join comm on t.comm_code = comm.comm_code -- this table not in sample given
where comm.comm_code IS NULL -- use instead of NOT EXISTS
)
SELECT DISTINCT
t.comm_code
, ca.id as fk_classification_id_a
, cb.id as fk_classification_id_b
, t.comm_max_year
FROM transCTE t
LEFT JOIN comm_info_a mia ON mia.comm_code = t.comm_code
LEFT JOIN classifications ca ON mia.classification_code = ca.classification_code
AND t.comm_max_year BETWEEN ca.valid_from AND ca.valid_to
LEFT JOIN comm_info_b mib ON mib.comm_code = t.comm_code
LEFT JOIN classifications cb ON mib.classification_code = cb.classification_code
AND t.comm_max_year BETWEEN cb.valid_from AND cb.valid_to
ORDER BY
t.comm_code
;
GO
comm_code | fk_classification_id_a | fk_classification_id_b | comm_max_year
:--------- | :--------------------- | :--------------------- | :------------
0100100000 | 10 | 5 | 2017
5002310010 | 5 | 2 | 2014
8090010000 | 3 | null | 2018
Demo at dbfiddle here
CREATE TABLE transactions (
[comm_code] [varchar](50) NULL,
[year] [varchar](255) NULL
--Rest of constraints...
)
insert into transactions (comm_code, year) values
('0100100000', 2013),
('0100100000', 2015),
('0100100000', 2017),
('8090010000', 2009),
('8090010000', 2010),
('8090010000', 2011),
('8090010000', 2015),
('8090010000', 2017),
('8090010000', 2018),
('5002310010', 2008),
('5002310010', 2014)
;
GO
11 rows affected
CREATE TABLE classifications (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[classification_code] [varchar](20) NOT NULL,
[description] [varchar](255) NULL,
[valid_from] [int] NULL,
[valid_to] [int] NULL
--Rest of constraints...
)
insert into classifications (classification_code, description, valid_from, valid_to)
values ('05012','Classification Number 1',2007,2012),
('05012','Classification Number 1',2013,2016),
('05012','Classification Number 1',2017,2020),
('12043','Classification Number 2',2007,2010),
('12043','Classification Number 2',2011,2020),
('12345','Classification Number 3',2013,2015),
('12345','Classification Number 3',2016,2020),
('54321','Classification Number 4',2007,2009),
('54321','Classification Number 4',2010,2013),
('54321','Classification Number 4',2014,2020)
;
GO
10 rows affected
CREATE TABLE comm_info_a (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[comm_code] [nchar](10) NOT NULL, /*should be unique*/
[classification_code] [nchar](6) NULL,
[thing] [nchar](6) NULL
--Rest of constraints...
);
GO
✓
insert into comm_info_a (comm_code, classification_code)
values ('0100100000','54321'),
('8090010000','05012'),
('5002310010','12043'),
('0987654321','54321')
;
GO
4 rows affected
CREATE TABLE comm_info_b (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[comm_code] [nchar](10) NOT NULL, /*should be unique*/
[classification_code] [nchar](6) NULL
--Rest of constraints...
);
GO
✓
insert into comm_info_b (comm_code, classification_code)
values ('0100100000','12043'),
('8090010000','00000'),
('5002310010','05012'),
('1234567890','12345');
GO
4 rows affected

How to combine multiple rows in T-SQL

Using SQL Server 2012: I have a simple table:
CREATE TABLE simpletable
(
[key] INT NOT NULL IDENTITY(1,1),
[id] INT,
[ca] INT,
[cp] INT,
[ct] INT
)
For various reasons this table only has a single row per [ca], [cp] and [ct] - like this:
INSERT INTO simpletable ([id], [ca], [cp], [ct])
VALUES (1, 10, null, null),
(1, null, 20, null),
(1, null, 120, null),
(1, null, null, 30),
(2, 11, null, null),
(2, null, 21, null),
(2, null, null, 31),
(2, null, null, 231)
What I would like to achieve (without cursors) is to explode out all the combinations into a temp table or a table-type variable; something like this:
id ca cp ct
---------------
1 10 20 30
1 10 120 30
2 11 21 31
2 11 21 231
I'd really appreciate your help on this.
Here is one (Cumbersome) way to do it:
SELECT dca.[id], dca.[ca], dcp.[cp], dct.[ct]
FROM
(
SELECT [id], [ca]
FROM simpletable
WHERE [ca] IS NOT NULL
) dca
INNER JOIN
(
SELECT [id], [cp]
FROM simpletable
WHERE [cp] IS NOT NULL
) dcp ON dca.id = dcp.id
INNER JOIN
(
SELECT [id], [ct]
FROM simpletable
WHERE [ct] IS NOT NULL
) dct ON dca.id = dct.id
See a live demo on rextester
Note this solution is based on the assumption that there must be at least one column other then id that is not null in every row.

is it possible to add duplicate values to usn column? this is the table i have created,how to add data something like i have shown in the example?

CREATE TABLE [dbo].[studentdb] (
[usn] VARCHAR (15) NOT NULL,
[name] VARCHAR (50) NOT NULL,
[collegename] VARCHAR (50) NOT NULL,
[eventid] VARCHAR (15) NOT NULL,
[passwd] VARCHAR (50) NULL,
[email] VARCHAR (75) NULL,
CONSTRAINT [PK_studentdb] PRIMARY KEY CLUSTERED ([usn] ASC, [eventid] ASC),
FOREIGN KEY ([eventid]) REFERENCES [dbo].[eventdb] ([eventid])
);
is it possible to add duplicate values to usn column?
this is the table i have created,how to add data something like i have shown in the example?
USN EVENTID
1 100
2 100
3 200
1 200
3 100
4 100
5 100
5 200
Your PRIMARY KEY is compound key. It is based on two columns ([usn] ASC, [eventid] ASC) so as long as pair is unique you can insert it.
In your example:
1 100
2 100
3 200
1 200
3 100
4 100
5 100
5 200
every pair is unique.
For inserting data use INSERT INTO syntax like:
INSERT INTO [dbo].[studentdb](
[usn],
[name],
[collegename],
[eventid],
[passwd],
[email])
VALUES (1, 100, ...), -- rest of values
(2, 100, ...),
...;

Resources