SQL Server group by 2 columns - generate sequence number - sql-server

I have table like below,
create table #temp
(
Name varchar(100),
Id int,
)
Insert into #temp values ('AAA',101)
Insert into #temp values ('AAA',102)
Insert into #temp values ('AAA',102)
Insert into #temp values ('AAA',103)
Insert into #temp values ('AAA',103)
Insert into #temp values ('BBB',201)
Insert into #temp values ('BBB',201)
Insert into #temp values ('BBB',202)
Insert into #temp values ('BBB',203)
Expected output:
Name Id Seq
-------------------
AAA 101 1
AAA 102 2
AAA 102 2
AAA 103 3
AAA 103 3
BBB 201 1
BBB 201 1
BBB 202 2
BBB 203 3
I want to generate sequence number based on name and Id. If Id is same, same sequence number needs to be assign.

Use DENSE_RANK:
SELECT
Name,
Id,
DENSE_RANK() OVER (PARTITION BY Name ORDER BY Id) Seq
FROM #temp;
Demo

Related

parent id hierarchy identification MS SqlServer2012

I have this code
create table #temp
(
order_id int not null identity(1,1) primary key
,sid int
,created_date date
,parent_order_id int
)
insert into #temp
(
sid
,created_date
)values(1,'2017-01-01')
insert into #temp
(
sid
,created_date
,parent_order_id
)values(1,'2017-02-01',1),(1,'2017-03-01',2),(1,'2017-04-01',3)
insert into #temp
(
sid
,created_date
)values(1,'2017-06-01')
insert into #temp
(
sid
,created_date
,parent_order_id
)values(1,'2017-07-01',5),(1,'2017-08-01',6)
select * from #temp
Whenever parent_order_id is null which indicates it is a new order. After that customer can add items associated to that order. so we have parent_order_id filled for these associations. But I want to know what is the first order_id for each association child order.I am looking for an output like below.
`order_id sid created_date parent_order_id original_order_id
1 1 2017-01-01 NULL 1
2 1 2017-02-01 1 1
3 1 2017-03-01 2 1
4 1 2017-04-01 3 1
5 1 2017-06-01 NULL 4
6 1 2017-07-01 5 4
7 1 2017-08-01 6 4
`
any help is appreciated. Thanks in advance.
With the following piece of code you can get results you are expecting.
;WITH cte (order_id, original_order_id)
AS
(
SELECT order_id, order_id AS original_order_id
FROM #temp WHERE parent_order_id IS NULL
UNION ALL
SELECT o.order_id AS order_id, cte.original_order_id AS original_order_id
FROM #temp AS o
JOIN cte
ON o.parent_order_id = cte.order_id
)
SELECT #temp.order_id, #temp.sid, #temp.created_date, #temp.parent_order_id, cte.original_order_id
FROM #temp
JOIN cte ON cte.order_id=#temp.order_id
ORDER BY cte.order_id
Please be aware, that there are certain limits on recursion as this for CTE. Currently it is 100 which can be pushed up to 32767.

Left join get all data in both table

I have two tables Q and A,
records are A are
QID UserID Value
1 100 A
2 100 B
3 100 C
1 101 AA
2 101 BB
3 101 CC
1 102 AAA
2 102 BBB
As you can see, there is no record for user 102 for QID 3. There is this another table Q.
QID Value
1 Name
2 Email
3 Site
What I want is, for each user, weather they have answered a question or not (that is, weather a entry exits in A table or not) I want all questions for all users and their answers. Something like this.
QID QValue UserID Value
1 Name 100 A
2 Email 100 B
3 Site 100 C
1 Name 101 AA
2 Email 101 BB
3 Site 101 CC
1 Name 102 AAA
2 Email 102 BBB
What the problem is one row is missing from the desired output, and that is
3 Site 102 NULL
Because for user 102 there is no entry in A table. I tried LEFT JOIN, but obviously it won't give the desired result as all the left table are already there. And INNER JOIN doesn't works either.
It is also complete possible for answers table (table A) to have data like this
QID QValue UserID Value
1 Name 100 A
2 Email 101 BB
3 Site 102 CCC
Say, all users just have filled in one record, in this case desired output is something like this
QID QValue UserID Value
1 Name 100 A
2 Email 100 NULL
3 Site 100 NULL
1 Name 101 NULL
2 Email 101 BB
3 Site 101 NULL
1 Name 102 NULL
2 Email 102 NULL
3 Email 102 CCC
If I do a LEFT JOIN on QID it doesn't works. Please suggest what should be done.
Try this:
declare #A table(QID int, UserID int, Value varchar(10))
declare #Q table(QID int, Value varchar(10))
insert into #A values (1, 100, 'A')
insert into #A values (2, 100, 'B')
insert into #A values (3, 100, 'C')
insert into #A values (1, 101, 'AA')
insert into #A values (2, 101, 'BB')
insert into #A values (3, 101, 'CC')
insert into #A values (1, 102, 'AAA')
insert into #A values (2, 102, 'BBB')
insert into #Q values (1, 'Name')
insert into #Q values (2, 'Email')
insert into #Q values (3, 'Site')
select
U.UserID,
Q.QID,
Q.Value as QValue,
A.Value
from
(select distinct UserID from #A) U -- all Users
cross join #Q Q -- all Questions
left outer join #A A on A.UserID = U.UserID and A.QID = Q.QID
So basically you do a cross join between all questions and all users first to get all combinations. Then you take this result and do a left join with all the answers. Missing answers will have NULL values in the Value (the real answer) field.

SQL Server - Update Column with Handing Duplicate and Unique Rows Based Upon Timestamp

I'm working with SQL Server 2005 and looking to export some data off of a table I have. However, prior to do that I need to update a status column based upon a field called "VisitNumber", which can contain multiple entries same value entries. I have a table set up in the following manner. There are more columns to it, but I am just putting in what's relevant to my issue
ID Name MyReport VisitNumber DateTimeStamp Status
-- --------- -------- ----------- ----------------------- ------
1 Test John Test123 123 2014-01-01 05.00.00.000
2 Test John Test456 123 2014-01-01 07.00.00.000
3 Test Sue Test123 555 2014-01-02 08.00.00.000
4 Test Ann Test123 888 2014-01-02 09.00.00.000
5 Test Ann Test456 888 2014-01-02 10.00.00.000
6 Test Ann Test789 888 2014-01-02 11.00.00.000
Field Notes
ID column is a unique ID in incremental numbers
MyReport is a text value and can actually be thousands of characters. Shortened for simplicity. In my scenario the text would be completely different
Rest of fields are varchar
My Goal
I need to address putting in a status of "F" for two conditions:
* If there is only one VisitNumber, update the status column of "F"
* If there is more than one visit number, only put "F" for the one based upon the earliest timestamp. For the other ones, put in a status of "A"
So going back to my table, here is the expectation
ID Name MyReport VisitNumber DateTimeStamp Status
-- --------- -------- ----------- ----------------------- ------
1 Test John Test123 123 2014-01-01 05.00.00.000 F
2 Test John Test456 123 2014-01-01 07.00.00.000 A
3 Test Sue Test123 555 2014-01-02 08.00.00.000 F
4 Test Ann Test123 888 2014-01-02 09.00.00.000 F
5 Test Ann Test456 888 2014-01-02 10.00.00.000 A
6 Test Ann Test789 888 2014-01-02 11.00.00.000 A
I was thinking I could handle this by splitting each types of duplicates/triplicates+ (2,3,4,5). Then updating every other (or every 3,4,5 rows). Then delete those from the original table and combine them together to export the data in SSIS. But I am thinking there is a much more efficient way of handling it.
Any thoughts? I can accomplish this by updating the table directly in SQL for this status column and then export normally through SSIS. Or if there is some way I can manipulate the column for the exact conditions I need, I can do it all in SSIS. I am just not sure how to proceed with this.
WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY VisitNumber ORDER BY DateTimeStamp) rn from MyTable
)
UPDATE cte
SET [status] = (CASE WHEN rn = 1 THEN 'F' ELSE 'A' END)
I put together a test script to check the results. For your purposes, use the update statements and replace the temp table with your table name.
create table #temp1 (id int, [name] varchar(50), myreport varchar(50), visitnumber varchar(50), dts datetime, [status] varchar(1))
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (1,'Test John','Test123','123','2014-01-01 05:00')
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (2,'Test John','Test456','123','2014-01-01 07:00')
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (3,'Test Sue','Test123','555','2014-01-01 08:00')
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (4,'Test Ann','Test123','888','2014-01-01 09:00')
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (5,'Test Ann','Test456','888','2014-01-01 10:00')
insert into #temp1 (id,[name],myreport,visitnumber, dts) values (6,'Test Ann','Test789','888','2014-01-01 11:00')
select * from #temp1;
update #temp1 set status = 'F'
where id in (
select id from #temp1 t1
join (select min(dts) as mindts, visitnumber
from #temp1
group by visitNumber) t2
on t1.visitnumber = t2.visitnumber
and t1.dts = t2.mindts)
update #temp1 set status = 'A'
where id not in (
select id from #temp1 t1
join (select min(dts) as mindts, visitnumber
from #temp1
group by visitNumber) t2
on t1.visitnumber = t2.visitnumber
and t1.dts = t2.mindts)
select * from #temp1;
drop table #temp1
Hope this helps

Expand row results based on a value in column (with iterator)

Need help from you all in writing up this query. Running SQL 2005 Standard edition.
I have a basic query that gets a subset of records from a table where the record_Count is greater then 1.
SELECT *
FROM Table_Records
WHERE Record_Count > 1
This query gives me a result set of, say:
TableRecords_ID Record_Desc Record_Count
123 XYZ 3
456 PQR 2
The above query needs to be modified so that each record appears as many times as the Record_Count and has its iteration number with it, as a value. So the new query should return results as follows:
TableRecords_ID Record_Desc Record_Count Rec_Iteration
123 XYZ 3 1
123 XYZ 3 2
123 XYZ 3 3
456 PQR 2 1
456 PQR 2 2
Could anyone help we write this query up? appreciate the help.
Clarification: Rec_Iteration column is a sub representation of the Record_Count. Basically, since there are three Record_Count for XYZ description thus three rows were returned with the Rec_Iteration representing the Row one , two and three respectively.
You can use a recursive CTE for this query. Below I use a table variable #T instead of your table Table_Records.
declare #T table(TableRecords_ID int,Record_Desc varchar(3), Record_Count int)
insert into #T
select 123, 'XYZ', 3 union all
select 456, 'PQR', 2
;with cte as
(
select TableRecords_ID,
Record_Desc,
Record_Count,
1 as Rec_Iteration
from #T
where Record_Count > 1
union all
select TableRecords_ID,
Record_Desc,
Record_Count,
Rec_Iteration + 1
from cte
where Rec_Iteration < Record_Count
)
select TableRecords_ID,
Record_Desc,
Record_Count,
Rec_Iteration
from cte
order by TableRecords_ID,
Rec_Iteration

Update rows by separating values from one column and inserting into 2 diff. columns

For eg. I have table T1. There are 4 columns in it c1 c2 c3 and c4. I have c1 as id, c2 contains combine name and address. c3 and c4 are empty. There are multiple rows for given id. Let's say there are 10 rows for id=10.
What I want is for all the rows with id=10, I want to read c2, separate values in c2 as name and address and store name in c3 and address in c4.
How can I do this in SQL server 2005/2008?
Thanks
Try:
UPDATE YourTable
SET c3=LEFT(c2,CHARINDEX(' ',c2))
,c4=RIGHT(c2,LEN(c2)-CHARINDEX(' ',c2))
WHERE c1=#YourIdValue
In the question, the method to separate values in c2 as name and address is not described, so I just split column c2 based on the first space found. c2='abcd efgh' becomes: c3='abcd', c4='efgh'.
Working sample:
DECLARE #YourTable table (c1 int,c2 varchar(10),c3 varchar(10),c4 varchar(10))
INSERT #YourTable VALUES (1,'aaaa bbbb',null,null)
INSERT #YourTable VALUES (1,'aaa bbb' ,null,null)
INSERT #YourTable VALUES (1,'aa bb' ,null,null)
INSERT #YourTable VALUES (1,'a b' ,null,null)
INSERT #YourTable VALUES (2,'222 333' ,null,null)
INSERT #YourTable VALUES (2,'aaa bbb' ,null,null)
INSERT #YourTable VALUES (3,'a b' ,null,null)
DECLARE #YourIdValue int
SET #YourIdValue=1
UPDATE #YourTable
SET c3=LEFT(c2,CHARINDEX(' ',c2))
,c4=RIGHT(c2,LEN(c2)-CHARINDEX(' ',c2))
WHERE c1=#YourIdValue
SELECT * FROM #YourTable
OUTPUT:
c1 c2 c3 c4
----------- ---------- ---------- ----------
1 aaaa bbbb aaaa bbbb
1 aaa bbb aaa bbb
1 aa bb aa bb
1 a b a b
2 222 333 NULL NULL
2 aaa bbb NULL NULL
3 a b NULL NULL
(7 row(s) affected)

Resources