I have a table with below structure:
+-------+-----------+--------+----------+--------+
| RefNo | TranType | Code | Remarks | Amount |
+-------+-----------+--------+----------+--------+
| 1 | BD | 400201 | abcc dfr | 200 |
| 1 | BD | 400202 | abcc dfr | 200 |
| 2 | BD | 400204 | defrt | 300 |
| 2 | BD | 400205 | defrt | 300 |
+-------+-----------+--------+----------+--------+
I need to transpose these values to the below format:
+-------+--------+--------+----------+----------+--------+
| RefNo | Code1 | Code2 | TranType | Remarks | Amount |
+-------+--------+--------+----------+----------+--------+
| 1 | 400201 | 400202 | BD | abcc dfr | 200 |
| 2 | 400204 | 400205 | BD | defrt | 300 |
+-------+--------+--------+----------+----------+--------+
You don't need to use PIVOT, you can do it using a simple query.
SELECT t1.refno,
t1.code AS Code1,
t2.code AS Code2,
t1.trantype,
t1.amount
FROM #table t1
INNER JOIN #table t2
ON t1.refno = t2.refno
AND T1.code < T2.code
Online Demo
You can try the following query.
;WITH Tab (RefNo,Code,TranType,Remarks,Amount,rowno)
AS
(SELECT T.RefNo
, T.Code
,TranType
,Remarks
,Amount
, RN = ROW_NUMBER() OVER (PARTITION BY T.RefNo ORDER BY T.Code )
FROM Table1 T)
SELECT RefNo,Code1 = MAX( CASE WHEN N.rowno=1 THEN N.Code ELSE 0 END ),
Code2 = MAX( CASE WHEN N.rowno=2 THEN N.Code ELSE 0 END ) ,
TranType,Remarks,Amount FROM Tab n
GROUP BY N.RefNo,TranType,Remarks,Amount
Related
I have three tables as below
Table 1 - DevInfo
+----------+--------+-----------+-------------+------+
| Center | DevId | DevType |LatestDate | DEL |
+----------+--------+-----------+-------------+------+
| C1 | 111 | T1 | 01/06/2020 | 0 |
| C1 | 222 | T2 | 01/06/2020 | 0 |
| C2 | 111 | T3 | 01/06/2020 | 0 |
| C2 | 333 | T4 | 01/06/2020 | 0 |
| C3 | 222 | T5 | 03/06/2020 | 0 |
| C4 | 444 | T6 | 01/06/2020 | 0 |
+----------+--------+-----------+-------------+------+
Table 2 - CenInfo
+----------+-------------+
| Center |LatestDate |
+----------+-------------+
| C1 | 01/06/2020 |
| C1 | 01/06/2020 |
| C2 | 01/06/2020 |
| C2 | 01/06/2020 |
| C3 | 03/06/2020 |
| C4 | 01/06/2020 |
+----------+-------------+
Table 3 - TypeInfo
+-----------+-------------+
| DevType |LatestDate |
+-----------+-------------+
| T1 | 01/06/2020 |
| T2 | 01/06/2020 |
| T3 | 01/06/2020 |
| T4 | 01/06/2020 |
| T5 | 03/06/2020 |
| T6 | 01/06/2020 |
+-----------+-------------+
I want to get data from DevInfo table, where
DevInfo table's center is same as in CenInfo table and DevInfo table's Dev Type is same as in TypeInfo table.
If DevId is same(e.g 111) for records then skip the record with DevType = "T3"
If DevId is same for records and DevType is not "T3" then select record with latest "LatestDate" value.
I want output like this:
+----------+--------+-----------+-------------+
| Center | Dev id | Dev Type |Latest Date |
+----------+--------+-----------+-------------+
| C1 | 111 | T1 | 01/06/2020 |
| C2 | 333 | T4 | 01/06/2020 |
| C3 | 222 | T5 | 03/06/2020 |
| C4 | 444 | T6 | 01/06/2020 |
+----------+--------+-----------+-------------+
I get the answer of 1st using an Inner Join,
Query as below :
Select
Center, DevId, DevType, LatestDate
From DevInfo DI
INNER JOIN CenInfo CI ON CI.Center = DI.Center
INNER JOIN TypeInfo TI ON TI.DevType = DI.DevType
WHERE DI.DEL = '0'
but didn't get any solution for 2 and 3
Please help me with that.
Thank you in advance.
You can use windowed ROW_NUMBER function:
WITH DevInfoFilteredAndSorted AS (
SELECT
DI.Center,
DI.DevId,
DI.DevType,
DI.LatestDate,
ROW_NUMBER() OVER (PARTITION BY DI.DevId ORDER BY CASE WHEN DI.DevType = 'T3' THEN 1 ELSE 0 END, DI.LatestDate DESC) AS RN
FROM DevInfo AS DI
INNER JOIN CenInfo AS CI
ON DI.Center = CI.Center
INNER JOIN TypeInfo AS TI
ON DI.DevType = TI.DevType
WHERE DI.DEL = 0
)
SELECT DI.Center, DI.DevId AS "Dev id", DI.DevType AS "Dev Type", DI.LatestDate AS "Latest Date"
FROM DevInfoFilteredAndSorted AS DI
WHERE DI.RN = 1
Example on dbfiddle.uk
Use CTE to get RowNumber as per your desired criteria and then perform join like below.
WITH DI AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY DevId ORDER BY IIF(DevType = 'T3', 1, 0), LatestDate DESC) AS RowNumber
FROM DevInfo
)
SELECT DI.Center, DI.DevId, DI.DevType, DI.LatestDate
From DI
INNER JOIN CenInfo CI ON CI.Center = DI.Center
INNER JOIN TypeInfo TI ON TI.DevType = DI.DevType
WHERE DI.RowNumber = 1
My Input Table is
+--------+----------+----------+-------+
| userid | teamname | task1 | task2 |
+--------+----------+----------+-------+
| 101 | T1 | 101task1 | desc1 |
| 101 | T1 | 101task2 | desc2 |
| 101 | T2 | 101task1 | desc3 |
| 101 | T2 | 101task2 | desc4 |
| 101 | T2 | 101task2 | desc5 |
| 102 | T3 | 102task1 | desc6 |
| 102 | T3 | 102task2 | desc7 |
| 102 | T3 | 102task3 | desc8 |
| 102 | T3 | 102task4 | desc9 |
+--------+----------+----------+-------+
I want the output as follow, to pivot(dynamic) task1+task2
+--------+----------+----------------+----------------+----------------+----------------+
| userid | teamname | 1 | 2 | 3 | 4 |
+--------+----------+----------------+----------------+----------------+----------------+
| 101 | T1 | 101task1 desc1 | 101task2 desc2 | | |
| 101 | T2 | 101task1 desc3 | 101task2 desc4 | 101task2 desc5 | |
| 102 | T3 | 102task1 desc6 | 102task2 desc7 | 102task3 desc8 | 102task4 desc9 |
+--------+----------+----------------+----------------+----------------+----------------+
I tried to pivot task1 and it worked like sample code SampleCode,
but when I pivot max(task1+task2) I get error
You need to combine them in source of pivot table and use them by giving them an alias.
set #query = 'SELECT userid,teamname,' + #cols + ' from
(
select userid,
teamname,
concat(task1,task2) as col, --Combine here
ROW_NUMBER() OVER(PARTITION BY userid,teamname order by task1 asc) AS Row#
from #yt
) x
pivot
(
max(col) --Alias used here
for row# in (' + #cols + ')
) p '
execute(#query);
Edit : To add a space in between fields
set #query = 'SELECT userid,teamname,' + #cols + ' from
(
select userid,
teamname,
CONCAT(task1,SPACE(1),task2) col,
ROW_NUMBER()OVER(PARTITION BY userid,teamname order by task1 asc) AS Row#
from #yt
) x
pivot
(
max(col)
for row# in (' + #cols + ')
) p '
execute(#query);
I've been working on this issue for the last day and a half and just can't seem to find another question on here that works for my code.
I have a table here:
Table_D
Policynumber| EntryDate | BI_Limit | P remium
------------------------------------------------------
ABCD100001 | 5/1/16 | 15/30 | 919
ABCD100001 | 5/13/16 | 15/30 | 1008
ABCD100002 | 5/24/16 | 100/300 | 1380
ABCD100003 | 5/30/16 | 25/50 | 1452
ABCD100003 | 6/2/16 | 25/50 | 1372
ABCD100003 | 6/4/16 | 30/60 | 951
ABCD100004 | 6/11/16 | 100/300 | 1038
ABCD100005 | 6/22/16 | 100/300 | 1333
ABCD100005 | 7/2/16 | 50/100 | 1208
ABCD100006 | 7/10/16 | 250/500 | 1345
ABCD100007 | 7/18/16 | 15/30 | 996
in which I'm trying to extract rows in which a policynumber has multiple listings and a different BI_Limit. So the output should be:
Output
Policynumber | EntryDate | BI_Limit | Premium
---------------------------------------------------
ABCD100003 | 5/30/16 | 25/50 | 1452
ABCD100003 | 6/2/16 | 25/50 | 1372
ABCD100003 | 6/4/16 | 30/60 | 951
ABCD100005 | 6/22/16 | 100/300 | 1333
ABCD100005 | 7/2/16 | 50/100 | 1208
I'm storing Policynumber as VARCHAR(Max), EntryDate as DATE, BI_Limit as VARCHAR(Max), and Premium as INTEGER.
The code I've want to say should work would be something along the lines of:
SELECT * FROM Table_D
WHERE BI_Limit IN (
SELECT BI_Limit
FROM Table_D
GROUP BY BI_Limit
HAVING COUNT(DISTINCT BI_Limit)>1);
But this returns nothing for me. Can anyone help to show me what I'm doing wrong? Thank you.
You could also try exists
select a.*
from Table_D a
where
exists (
select 1
from Table_D b
where a.Policynumber = b.Policynumber
and a.BI_Limit <> b.BI_Limit
)
SELECT d.*
FROM ( -- find the policy number with multiple listing and diff BI_Limit
SELECT PolicyNumber
FROM TableD
GROUP BY PolicyNumber
HAVING count(*) > 1
AND MIN (BI_Limit) <> MAX (BI_Limit)
) m -- join back the Table_D to for other information
INNER JOIN Table_D d
ON m.PolicyNumber = d.PolicyNumber
Based on the product and product key, update the column ord_by. There should be only one min and max for a product and product_key .
E.g: Table
+-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
| 1 | ABC | 10 | |
| 1 | ABC | 10 | |
| 1 | ABC | 20 | |
| 1 | ABC | 100 | |
| 1 | ABC | 100 | |
| 2 | EFG | 20 | |
| 2 | EFG | 40 | |
| 3 | ABC | 100 | |
+-------------+---------+-------+--------+
Expected output:
+-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
| 1 | ABC | 10 | Min |
| 1 | ABC | 10 | Mid |
| 1 | ABC | 20 | Mid |
| 1 | ABC | 100 | Mid |
| 1 | ABC | 100 | Max |
| 2 | EFG | 20 | Min |
| 2 | EFG | 40 | Max |
| 3 | ABC | 100 | None |
+-------------+---------+-------+--------+
My try :
;WITH ord_cte
AS (
SELECT product
,product_key
,max(price) as max_price
,min(price) as min_price
FROM t_prod_ord
group by product,product_key
)
UPDATE t1
SET ord_by = case
when t2.max_price =t2.min_price then 'none'
when t2.max_price=t1.price then 'max'
when t2.min_price=t1.price then 'min'
else 'mid' end
FROM t_prod_ord t1
INNER JOIN ord_cte t2 ON t1.product_key = t2.product_key and t1.product=t2.product
using this query it is updating more than one max and min value for column ord_by.
Generate row number for each Product_key order by Price in both ASC and DESC order. Then use the row number in CASE statement to find the Min/Max values
Count() Over() aggregate window function will help you find the total count of each Product_key which we can use it for finding None
Here is one way
;WITH cte
AS (SELECT *,
Row_number()OVER(PARTITION BY Product_key ORDER BY price) AS Min_KEY,
Row_number()OVER(PARTITION BY Product_key ORDER BY price DESC) AS Max_KEY,
Count(1)OVER(partition BY Product_key) AS cnt
FROM Yourtable)
SELECT Product_key,
product,
price,
CASE
WHEN cnt = 1 THEN 'None'
WHEN Min_KEY = 1 THEN 'Min'
WHEN Max_Key = 1 THEN 'Max'
ELSE 'Mid'
END
FROM cte
Another way to do with out cte...
SELECT [Product_key],
[product],
[price],
CASE
WHEN Max(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
)=1 AND RN=1 THEN 'NONE'
WHEN Min(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
) = RN THEN 'MIN'
WHEN Max(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
) = RN THEN 'MAX'
ELSE 'MID'
END ORDER_BY
FROM (SELECT *,
Row_number()
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
ORDER BY PRICE) RN
FROM TABLE1)Z
Hello I have a temp table (#tempResult) that contains results like the following...
-----------------------------------------
| DrugAliasID | Dosage1 | Unit1 | rowID |
-----------------------------------------
| 322 | 10 | MG | 1 |
| 322 | 50 | ML | 2 |
| 441 | 20 | ML | 3 |
| 443 | 15 | ML | 4 |
-----------------------------------------
I'm looking to get the results to be like the following, pivoting the rows that have the same DrugAliasID.
--------------------------------------------------
| DrugAliasID | Dosage1 | Unit1 | Dosage2 | Unit2 |
--------------------------------------------------
| 322 | 10 | MG | 50 | ML |
| 441 | 20 | ML | NULL | NULL |
| 443 | 15 | ML | NULL | NULL |
--------------------------------------------------
So far I have a solution that isn't using pivot. I'm not too good with pivot and was wondering if anyone knew how to use it in this scenario. Or solve it some other way. Thanks
SELECT
tr.drugAliasID,
MIN(trmin.dosage1) AS dosage1,
MIN(trmin.unit1) AS unit1,
MIN(trmax.dosage1) AS dosage2,
MIN(trmax.unit1) AS unit2
FROM
#tempResult tr
JOIN
#tempResult trmin ON trmin.RowID = tr.rowid AND trmin.drugAliasID = tr.drugAliasID
JOIN
#tempResult trmax ON trmax.RowID = tr.rowid AND trmax.drugAliasID = tr.drugAliasID
JOIN
(SELECT
MIN(RowID) AS rowid,
drugAliasID
FROM
#tempResult
GROUP BY
drugAliasID) tr1 ON tr1.rowid = trmin.RowID
JOIN
(SELECT
MAX(RowID) AS rowid,
drugAliasID
FROM
#tempResult
GROUP BY
drugAliasID) tr2 ON tr2.rowid = tr.RowID
GROUP BY
tr.drugAliasID
HAVING
count(tr.drugAliasID) > 1
Assuming your version of SQL Server supports the use of CTEs, you can simplify your query thus:
;with cte as
(select *, row_number() over (partition by drugaliasid order by rowid) rn
from #tempResult
)
select c.drugaliasid, c.dosage1, c.unit1, c2.dosage1 as dosage2, c2.unit1 as unit2
from cte c
left join cte c2 on c.drugaliasid = c2.drugaliasid and c.rn = 1 and c2.rn = 2
where c.rn = 1
Demo
This will give you the desired result, without having to use the pivot keyword.