Combine values of two rows into single row using SQL [closed] - sql

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
ID QuestionNo AnswerPercent
1 15 10
1 16 10
1 17 20
1 18 25
2 15 30
2 16 0
2 17 15
2 18 25
Output
ID QuestionNo AnswerPercent
1 15 10
1 16 30
1 17 20
1 18 25
2 15 30
2 16 15
2 17 15
2 18 25
For each id the answer percent for questions 16 and 17 need to be merged into 16. Chances are for some ids there may not be any 16 or 17 question numbers.
Can anyone help me out in this. Thanks!.

I believe this is what you're after, an UPDATE with a JOIN to a subquery:
UPDATE A
SET A.AnswerPercent = B.AnswerPercent
FROM YourTable A
JOIN (SELECT ID, SUM(AnswerPercent)'AnswerPercent'
FROM YourTable
WHERE QuestionNo IN ('16','17')
GROUP BY ID
)B
ON A.ID = B.ID
WHERE A.QuestionNo = '16'
Demo: SQL Fiddle

try adding the table twice...
table aliased as a has all rows except the ones for question 17, and
table aliased as b has the rows for question 17
Select a.Id, a.QuestionNo,
a.AnswerPercent +
case A.QuestionNo When 16
then coalesce(b.AnswerPercent, 0) End
else 0 End AnswerPercent
From table a
left Join table b
on a.id = b.Id
And a.QuestionNo != 17
And b.QuestionNo = 17
if all you want is to update the existing table, then you need an update and a delete.
update a set
AnswerPercent = a.AnswerPercent +
IsNull(b.AnswerPercent, 0)
from table a
left Join table b
on a.id = b.Id
And a.QuestionNo = 16
And b.QuestionNo = 17
--and then ...
delete table where QuestionNo = 17

with aaa as(
select sum(AnswerPercent) as AnswerPercent,ID
from Table
where QuestionNo in (16,17)
group by ID)
select * from Table where QuestionNo <> 16
union
select ID, 16, sum
from aaa
order by ID,AnswerPercent

Related

How to fill in the gaps in a query of totals with zeroes?

I have a table with data like this
picks
20
20
20
18
17
12
12
9
9
This is the table but I need to get result like this.
Picks Count
20 3
19 0
18 1
17 1
16 0
...up to
1 12
How can we write query to get zero totals for data which doesn't exist in the table?
Arun
Use a subquery to generate all the numbers and then outer join it to your table.
with nos as ( select level as pick_id
from dual
connect by level <= 20 )
select nos.pick_id
, count(*)
from nos
left outer join picks
on nos.pick_id = picks.id
group by nos.pick_id
order by nos.pick_id desc ;

sql query adding previous value to next value [duplicate]

This question already has answers here:
Cumulative Total in MS Sql server [duplicate]
(6 answers)
Closed 8 years ago.
I want to add two columns values of my table E.g:
Id Distance Duration ETA_Distance ETA_Duration
1 0 0 20 60
2 14 20 NULL NULL
3 12 10 NULL NULL
4 15 70 NULL NULL
Considering the table above, I want a SQL query which give me the result like below:
Id Distance Duration ETA_Distance ETA_Duration
1 0 0 20 60
2 14 20 34 80
3 12 10 46 90
4 15 70 61 160
Mohan, see the below answer, It should help you.
Replace the #table with your table.
I used the temp table just to test the code.
Declare #tab table (Id int,Distance int, Duration int, ETA_Distance int, ETA_Duration int)
Insert into #tab values
(1,0 , 0,20 ,60 ),
(2,14, 20,NULL,NULL),
(3,12, 10,NULL,NULL),
(4,15, 70,NULL,NULL)
Select X.Id,X.Distance,X.Duration,
Y.ETA_Distance,Y.ETA_Duration
From #tab X
Join (
Select B.Id,
Sum(A.Distance) ETA_Distance,
Sum(A.Duration) ETA_Duration
From (Select Id,ISNULL(ETA_Distance,Distance) Distance,ISNULL(ETA_Duration,Duration) Duration From #tab) A,
(Select Id,ISNULL(ETA_Distance,Distance) Distance,ISNULL(ETA_Duration,Duration) Duration From #tab) B
Where A.Id <= B.Id
Group By B.Id) Y
On X.Id = Y. Id
Result:
Sql may look lengthy, but the logic is simple.

How to arrange sequence range in group by [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Hi all
i am facing a problem and need a query for that ,
I have a table and data like
----------
seq_id run_id mark_Flag
1 10 A
2 11 A
3 12 A
4 13 Z
5 14 A
6 15 A
7 16 Z
8 17 Z
9 18 A
10 19 A
11 20 Z
----------
Now i required the output like
seq runidFrom runidTo mark_Flag
1 10 12 A
2 13 13 Z
3 14 15 A
4 16 17 Z
5 18 19 A
6 20 20 Z
Thanks in advance ....
Try this query the main idea is to group by count of previous Mark_flag not equal to current
SELECT min(run_id),max(run_id),max(mark_Flag)
FROM T as T1
GROUP BY mark_flag,
(
SELECT COUNT(*) FROM T
WHERE seq_id<T1.seq_id
and
mark_flag<>T1.Mark_flag
)
ORDER BY MIN(seq_id)
SQLFiddle demo
This query have to work on any database system but when you post a question please add a tag with your RDBMS (not just SQL) so a query can be optimized for your data base system.
UPD: Here is the MS SQL version:
SELECT min(run_id),max(run_id),max(mark_Flag)
FROM
(
Select run_id, mark_flag,seq_id,
(
SELECT COUNT(*) FROM T
WHERE seq_id<T1.seq_id
and mark_flag<>T1.Mark_flag
) as group_id
From t as T1
) as T2
GROUP BY mark_flag,group_id
ORDER BY MIN(seq_id)
SQLFiddle demo

Finding the Missing Sequence SQL Server [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
CNo Wno Lno
12 1 1
12 1 2
12 2 3
12 3 15
9 1 1
13 1 1
13 2 2
13 3 5
10 1 1
10 1 2
10 1 3
10 2 4
11 1 1
for Cno i need the missing sequence numbers in Lno
Eg:
for Cn0=12
the line no is missing from 4 to 14
and for Cno=13 the sequence number(3,4) of Lno is missing
i need to find out the missing sequence no's for the clno
You can use common table expression for generating range of numbers and then find missing ones:
with cte as (
select t.CNo, min(t.Lno) as Lno, max(t.Lno) as max_Lno from Table1 as t
group by t.CNo
union all
select c.CNo, c.Lno + 1 as Lno, c.max_Lno
from cte as c
where c.Lno < c.max_Lno
)
select c.Cno, c.Lno
from cte as c
where
not exists (
select *
from Table1 as t
where t.CNo = c.CNo and t.Lno = c.Lno
)
order by 1, 2
option (maxrecursion 0);
if you have tables with sequential numbers, you can do this:
select c.Cno, n.n as Lno
from numbers as n
inner join (
select
tt.CNo, min(tt.Lno) as min_Lno, max(tt.Lno) as max_Lno
from Table1 as tt
group by tt.CNo
) as c on c.min_Lno <= n.n and c.max_Lno >= n.n
where
not exists (
select *
from Table1 as t
where t.CNo = c.CNo and t.Lno = n.n
)
order by 1, 2;
sql fiddle demo
not 100% sure what you are trying to do but you could use a number table to help with this.
if you have a table called numbers like this:
number
1
2
3
4
5.. up to highest number you are interested in
then you could do something like:
select
n.number
from
numbers as n
left outer join table as t
on n.number = t.Lno
and t.cno = 12
where
n.number <= (select max(lno) from table where cno = 12)
and t.nco is null
I don't know what type of output you are looking for or how you want to select the missing numbers you are looking for.

All possible combinations unpivoted

I've been working on a problem that I can't quite figure out. I've tried different combinations of cross joins, CTEs, windowing functions, etc but could never quite get there. I'm also not wanting to go the dynamic SQL route. Can someone please help?
Given a variable set of grouped values produce all possible combinations vertically (derived group, value)
Additional info:
No 2 combinations should have the same set of values, regardless of
order. Example: If you already have (1,2) then don't produce (2,1),
if (1,2,3) then no (1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)
Values of the same group should not combine
all values are unique, regardless of group. The only reason for the
initial grouping is to apply rule #2
Example:
Given the starting groups and values of
InputGroup Value
1 8
2 7
2 9
3 1
3 6
3 3
Produce this output
OutputGroup Value
1 8
2 7
3 9
4 1
5 6
6 3
7 8
7 7
8 8
8 9
9 8
9 1
10 8
10 6
11 8
11 3
12 7
12 1
13 7
13 6
14 7
14 3
15 9
15 1
16 9
16 6
17 9
17 3
18 8
18 7
18 1
19 8
19 7
19 6
20 8
20 7
20 3
21 8
21 9
21 1
22 8
22 9
22 6
23 8
23 9
23 3
Here's the manual, non-vertical method for producing the output
CREATE TABLE #temp1 (GroupID INT, MyValue INT)
INSERT INTO #temp1 (GroupID, MyValue)
VALUES (1,8),(2,7),(2,9),(3,1),(3,6),(3,3)
--1st set of possibilities
SELECT MyValue
FROM #temp1
--2nd set of possibilities
SELECT a.MyValue, b.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.GroupID < b.GroupID
--3rd set
SELECT a.MyValue, b.MyValue, c.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.GroupID < b.GroupID
JOIN #temp1 c
ON b.GroupID < c.GroupID
DROP TABLE #temp1
My problem is that there can be a variable number of starting values
With this in mind, my output needs to be in grouped vertical sets so I'm only returning 2 columns. 1 that groups the numbers together and the number itself.
For this specific example there should be 46 rows with 23 distinct groups as shown above
I wrote CTE that I kept modifying and finally scrapped:
WITH MyCTE
AS (SELECT 1 AS Level, DENSE_RANK() OVER (ORDER BY GroupID, MyValue) AS DgroupID, GroupID, MyValue
FROM #temp1
UNION ALL
SELECT a.Level + 1, DENSE_RANK() OVER (ORDER BY b.GroupID, b.MyValue), b.GroupID, b.MyValue
FROM MyCTE a
JOIN #temp1 b
ON a.GroupID < b.GroupID)
SELECT DENSE_RANK() OVER (ORDER BY Level, DgroupID), MyValue
FROM MyCTE
The obvious problems with this:
1) The windowing function I used to give an incremental value to each row didn't work as expected. This is probably due to the way CTEs work. Good for performance, bad for me. The ROW_NUMBER windowing function does the same thing. All I'm trying to do there is to autoincrement the rows within each iteration so I can identify the group when the table gets "unpivoted". I believe the reason CTEs are so fast is because they're actually set-based operations so even though there's recursion I can't rely on the loop/iteration mode of thinking to produce the intended result. Feel free to correct me in all of my assumptions
2) Unpivoting. I need to take a set of rows and unpivot the columns into rows, with each keeping the identifier of the original row to show they are grouped together. SQL Server has a wonderful command called UNPIVOT which doesn't help me at all because you need to know how many columns you're unpivoting at design time. The whole point of this is to be able to provide a variable number of inputs and produce a predictable output
So, you are trying to group all "Group 1" values with all "Group 2" values and all "Group 3" values, but prevent the duplicates as you stated of ex: 1,2 and 2,1. You manual approach looks ok, however I'm not getting why you are comparing groups as opposed to the "Values" being less than the prior such that..
SELECT a.MyValue, b.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.MyValue < b.MyValue AND a.GroupID <> b.GroupID
--3rd set
SELECT a.MyValue, b.MyValue, c.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.MyValue < b.MyValue AND a.GroupID <> b.GroupID
JOIN #temp1 c
ON b.MyValue < c.MyValue AND a.GroupID <> c.GroupID AND b.GroupID <> c.GroupID
Per your feedback, the above adjustments should work, it would just take take extra muscle as it would have to permeate through Group 1, Group 2 and also Group 2, Group 1 since the number 1 could exist in group 2, but group 1 has a low number of 5. If you are always qualifying a.Group less than b.Group, you would never have the value 1 in the first position as group 2 is greater than group 1.
Does that make sense to your scenario?