My table is:
Id Name Add
1 a A
2 b B
3 c C
4 d D
I want to displaty it as:
Id Name Add Id2 Name2 Add2
1 a A 2 b B
3 c C 4 d D
Use query below
Select LTable.id,LTable.Name,LTable.[Add],
RTable.id,RTable.Name,RTable.[Add]
from
(
Select Row_Number()over ( order by id)as fldkey,id,name , [Add]
from TableName
where id % 2 <> 0
) as LTable INNER JOIN
(
Select Row_Number()over ( order by id)as fldkey,id,name , [Add]
from TableName
where id % 2 = 0
) as RTable
on LTable.fldKey = RTable.fldKey
Related
I Have a table looks like this:
RowNum category Rank4A Rank4B
-------------------------------------------
1 A
2 A
3 B
5 A
6 B
9 B
My requirement is based on the RowNum order, Make two new ranking columns depend on category. Rank4A works like the DENSERANK() by category = A, but if the row is for category B, it derives the latest appeared rank for category A order by RowNum. Rank4B have similar logic, but it orders by RowNum in DESC order. So the result would like this (W means this cell I don't care its value):
RowNum category Rank4A Rank4B
-------------------------------------------
1 A 1 W
2 A 2 W
3 B 2 3
5 A 3 2
6 B W 2
9 B W 1
One more additional requirement is that CROSS APPLY or CURSOR is not allowed due to dataset being large. Any neat solutions?
Edit: Also no CTE (due to MAX 32767 limit)
You can use the following query:
SELECT RowNum, category,
SUM(CASE
WHEN category = 'A' THEN 1
ELSE 0
END) OVER (ORDER BY RowNum) AS Rank4A,
SUM(CASE
WHEN category = 'B' THEN 1
ELSE 0
END) OVER (ORDER BY RowNum DESC) AS Rank4B
FROM mytable
ORDER BY RowNum
Giorgos Betsos' answer is better, please read it first.
Try this out. I believe each CTE is clear enough to show the steps.
IF OBJECT_ID('tempdb..#Data') IS NOT NULL
DROP TABLE #Data
CREATE TABLE #Data (
RowNum INT,
Category CHAR(1))
INSERT INTO #Data (
RowNum,
Category)
VALUES
(1, 'A'),
(2, 'A'),
(3, 'B'),
(5, 'A'),
(6, 'B'),
(9, 'B')
;WITH AscendentDenseRanking AS
(
SELECT
D.RowNum,
D.Category,
AscendentDenseRanking = DENSE_RANK() OVER (ORDER BY D.Rownum ASC)
FROM
#Data AS D
WHERE
D.Category = 'A'
),
LaggedRankingA AS
(
SELECT
D.RowNum,
AscendentDenseRankingA = MAX(A.AscendentDenseRanking)
FROM
#Data AS D
INNER JOIN AscendentDenseRanking AS A ON D.RowNum > A.RowNum
WHERE
D.Category = 'B'
GROUP BY
D.RowNum
),
DescendantDenseRanking AS
(
SELECT
D.RowNum,
D.Category,
DescendantDenseRanking = DENSE_RANK() OVER (ORDER BY D.Rownum DESC)
FROM
#Data AS D
WHERE
D.Category = 'B'
),
LaggedRankingB AS
(
SELECT
D.RowNum,
AscendentDenseRankingB = MAX(A.DescendantDenseRanking)
FROM
#Data AS D
INNER JOIN DescendantDenseRanking AS A ON D.RowNum < A.RowNum
WHERE
D.Category = 'A'
GROUP BY
D.RowNum
)
SELECT
D.RowNum,
D.Category,
Rank4A = ISNULL(RA.AscendentDenseRanking, LA.AscendentDenseRankingA),
Rank4B = ISNULL(RB.DescendantDenseRanking, LB.AscendentDenseRankingB)
FROM
#Data AS D
LEFT JOIN AscendentDenseRanking AS RA ON D.RowNum = RA.RowNum
LEFT JOIN LaggedRankingA AS LA ON D.RowNum = LA.RowNum
LEFT JOIN DescendantDenseRanking AS RB ON D.RowNum = RB.RowNum
LEFT JOIN LaggedRankingB AS LB ON D.RowNum = LB.RowNum
/*
Results:
RowNum Category Rank4A Rank4B
----------- -------- -------------------- --------------------
1 A 1 3
2 A 2 3
3 B 2 3
5 A 3 2
6 B 3 2
9 B 3 1
*/
This isn't a recursive CTE, so the limit 32k doesn't apply.
I want to retrieve the set of data from a column in the table.
My Scenario is:
Iam having a table with name table1_data , In that table there is a Column with name "clm_Name", The data in the column is like this
a
b
c
a
b
c
a
b
a
b
c
a
a
b
c
I want to retrieve the data when a b c are in order if order changes it should not retrieve.(i.e, If we write a query on given data the output should be a b c a b c a b a b c a a b c) only the bolded letters should be shown in output.
If you have a column to sort you can do as follows:
DECLARE #Tbl TABLE (OrderId INT, val NVARCHAR(1))
INSERT INTO #Tbl
VALUES
(1,'a'),
(2,'b'),
(3,'c'),
(4,'a'),
(5,'b'),
(6,'c'),
(7,'a'),
(8,'b'),
(9,'a'),
(10,'b'),
(11,'c'),
(12,'a'),
(13,'a'),
(14,'b'),
(15,'c')
;WITH CTE
AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY (SELECT OrderId)) RowId
FROM #Tbl
), Result
AS
(
SELECT
CurrRow.RowId
FROM
CTE CurrRow LEFT JOIN
(SELECT CTE.val , CTE.RowId - 1 RowId FROM CTE) NextRow ON CurrRow.RowId = NextRow.RowId LEFT JOIN
(SELECT CTE.val , CTE.RowId + 1 RowId FROM CTE) PrivRow ON CurrRow.RowId = PrivRow.RowId
WHERE
PrivRow.val = 'a' AND
CurrRow.val = 'b' AND
NextRow.val = 'c'
)
SELECT
*
FROM
CTE C
WHERE
C.RowId IN (
SELECT Result.RowId FROM Result
UNION ALL
SELECT Result.RowId - 1 FROM Result
UNION ALL
SELECT Result.RowId + 1 FROM Result
)
ORDER BY C.OrderId
Output:
OrderId val RowId
1 a 1
2 b 2
3 c 3
4 a 4
5 b 5
6 c 6
9 a 9
10 b 10
11 c 11
13 a 13
14 b 14
15 c 15
I have this table:
ID TXT VL
----------
1 A 1
2 B 0
4 C 0
6 D 0
10 D 0
13 E 0
14 C 0
15 E 0
I have no idea how I can select only the first appearance of TXT like this:
ID TXT VL
----------
1 A 1
2 B 0
4 C 0
6 D 0
13 E 0
You can do the following:
select t1.*
from tbl t1
join (select min(id) as id from tbl group by txt) t2 on t1.id = t2.id
In the temporary table you find all first occurrences of each uniq txt and then join it with the original table.
You can do it with ROW_NUMBER() OVER, like this:
WITH CTE AS (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY TXT ORDER BY ID) AS RowN
FROM table
)
SELECT ID, TXT, VL
FROM CTE
WHERE RowN = 1
Hope it helps :)
For more reading:
https://msdn.microsoft.com/en-us/library/ms189461.aspx
And https://msdn.microsoft.com/en-us/library/ms186734.aspx
I have a table which has 3 columns A, B, C
I want to do a query like this:
select A, Max(B), ( C in the row having max B ) from Table group by A.
is there a way to do such a query?
Test Data:
A B C
2 5 3
2 6 1
4 5 1
4 7 9
6 5 0
the expected result would be:
2 6 1
4 7 9
6 5 0
;WITH CTE AS
(
SELECT A,
B,
C,
RN = ROW_NUMBER() OVER(PARTITION BY A ORDER BY B DESC)
FROM YourTable
)
SELECT A, B, C
FROM CTE
WHERE RN = 1
Try this
select t.*
from table t
join (Select A,max(b) B from table group by A) c
on c.a=t.a
and c.b=a.b
I have the following table, and I want to set the value of deleted column to zero for only one of the records that have duplicate names.
id name deleted
------------------------
1 a 1
2 a 1
3 a 1
4 b 1
5 c 1
6 d 1
so the output will be:
id name deleted
------------------------
1 a 0
2 a 1
3 a 1
4 b 0
5 c 0
6 d 0
If your dbms is SQL-Server( >= 2005) you can use a CTE with ROW_NUMBER:
WITH CTE AS
(
SELECT ID, Name, Deleted,
RN = ROW_NUMBER() OVER(PARTITION BY name ORDER BY ID)
FROM dbo.T
)
UPDATE CTE
SET Deleted = 0
WHERE RN = 1
DEMO
UPDATE Tbl SET deleted = 0 WHERE id IN
(SELECT MIN(id) FROM Tbl GROUP BY name)
UPDATE A
SET A.deleted = 0
FROM Tbl A
LEFT JOIN Tbl B
ON A.Name = B.Name
AND A.Id > B.Id
WHERE B.Id IS NULL