TSQL - Convert Rows per record to Columns - sql

Consider the following table:
+------------------------------------------------------------------------------+
| GUID | DeviceGUID | DetailGUID | sValue | iValue | gValue | DateStored |
| ENTRY1 | DEVICE1 | Detail1 | SN112 | | | 01/01/2020 |
| ENTRY2 | DEVICE1 | Detail4 | | 1241 | | 01/01/2020 |
| ENTRY3 | DEVICE1 | Detail7 | | | GUID12 | 01/01/2020 |
| ENTRY4 | DEVICE2 | Detail1 | SN111 | | | 01/01/2020 |
| ENTRY5 | DEVICE2 | Detail2 | RND123 | | | 01/01/2020 |
| ENRTY6 | DEVICE2 | Detail4 | | 2351 | | 03/01/2020 |
| ENTRY7 | DEVICE3 | Detail1 | SN100 | | | 02/01/2020 |
| [...] | [...] | [...] | | | | |
| | | | | | | |
+------------------------------------------------------------------------------+
I have a table which links a DeviceGUID with a DetailsGUID, with the idea of having unlimited options for Details (just create a new detail and it will be fetchable). however, this means I have a finite and unknown amount of records per deviceGUID.
What I want to show to my users is a table like this:
+--------+---------------------------------------------------------------------+
| GUID | DeviceGUID |Detail1 |Detail2 |Detail4 |Detail7 |DateStored |
| ENTRY1 | DEVICE1 |SN112 | [NULL] |1241 |GUID12 | [MAX DateStored] |
| ENTRY2 | DEVICE2 |SN111 | RND123 |2351 | [NULL] | [MAX DateStored] |
| ENTRY3 | DEVICE3 |SN100 | | | | |
| [...] | [...] | | | | | |
+------------------------------------------------------------------------------+
I have been searching a bit and found the PIVOT option but that only seems to function for one field,
another option was CROSS APPLY, but that (seems to) need to convert everything to the same datatype; as I hope is visible n the ColumnNames, I will have 3 types of data: String (VARCHAR) value, Integer value, GUID (uniqueidentifier) value, and they will not be interchangeable (meaning Detail with GUID Detail1 will always have a VARCHAR, Detail with DetailGUID Detail4 will always be an Integer
what I was able to find out until now:
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns+=N', p.'+QUOTENAME([Name])
FROM
(
SELECT GUID AS [Name]
FROM [dbo].Details AS p
) AS x;
SET #sql = N'
SELECT [DeviceObjectGUID], '+STUFF(#columns, 1, 2, '')+' FROM (
SELECT [DeviceObjectGUID], [DateStored], [DetailGUID] as [Name]
FROM [dbo].[DeviceDetails]) AS j PIVOT (MAX(DateStored) FOR [Name] in
('+STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')+')) AS p;';
EXEC sp_executesql #sql
to make a dynamic PIVOT for transposing the data.. but as mentioned this is limited to one column
and
select DeviceObjectGUID, value
from DeviceDetails
cross apply
(
select 'sValue', cast(sValue as varchar(MAX)) union all
select 'gValue', cast(gValue as varchar(MAX))union all
select 'iValue', cast(iValue as varchar(MAX))
) c(col, value)
This will have me converting all fields to VARCHAR..
One other option I tried (to understand PIVOT) was this:
SELECT *
FROM
(SELECT *
FROM [dbo].[DeviceDetails]
) AS SourceTable
PIVOT(
max(sValue)FOR [DetailGUID] IN(
[450533BB-43B2-499B-B2F7-094BFAE949B0],
[7483E518-EB61-4B72-93F7-0F97BBFAFA01],
[29B1BDE8-3AD4-4576-8B76-3CAE83E10B11],
[5FC8CC76-12EB-4924-9320-5D09BBE97C10],
[789AA79B-B1DF-4BA2-860A-7129B39D341F],
[C90F4EFE-D848-4BAB-96BF-8DC6BF4F6E62],
[EC6A4ED3-1475-4B0A-8E08-B2F4E095622F],
[D442B7CA-5825-49D9-9977-D88770304B57],
[99B70FEE-999B-4D44-83E9-EB8119B15930],
[3F83ED76-8CC3-4B3D-936A-F528DEB6C045]
)
) AS PivotTable;
(The GUIDS in the 'IN clause are the DetailGUIDs)
this almost gets me what I want, except that it is not dynamic and the fact that it is still limited to one data column. (max(sValue)) in this case.
===================
in response to

It should be as simple as that:
SELECT *
FROM
(
SELECT DeviceGUID
,DetailGUID
,CONCAT(sValue, iValue, gValue) as [value]
,DateStored
FROM my_table
) DS
PIVOT
(
MAX([value]) FOR DetailGUID IN (......)
) PVT

Related

how to fetch '/' separated node/tag name from a given xml in sql

i want to fetch '/' separated node name from a given xml such that only node/tag name are getting fetched instead of node/tag value from a given xml.
Suppose if i have below xml :
<ns:manageWorkItemRequest>
<ns:wiFocus>
<act:orderDate>2020-03-16T10:30:56.000Z</act:orderDate>
<act:orderItem>
<agr:instance>
<spec1:customerServiceIdentifier>ETHA15302121</spec1:customerServiceIdentifier>
<spec1:instanceCharacteristic>
<spec1:action>
<spec1:code>Modify</spec1:code>
</spec1:action>
<spec1:instanceIdentifier>
<spec1:value>OS014-AHEFV5T9</spec1:value>
</spec1:instanceIdentifier>
</agr:instance>
</act:orderItem>
<act:orderVersion>1</act:orderVersion>
</ns:wiFocus>
<ns:wiAction>Create</ns:wiAction>
<ns:wiVersion>1</ns:wiVersion>
</ns:manageWorkItemRequest>
I want result as :
ns:manageWorkItemRequest/ns:wiFocus/act:orderItem/agr:instance/spec1:customerServiceIdentifier/ETHA15302121
actually the requirement is if i get this "ETHA15302121" value in above xml then i should show the path i.e. where exactly in xml that value is in '/' separated format.
Your XML was not well-formed (missing closing tag in the middle and missing namespace declarations.
After adding the missing parts it looks as so and you might try something along this route (warning: this won't be fast...):
Your XML
DECLARE #xml XML=
N'<root xmlns:ns="dummy1" xmlns:act="dummy2" xmlns:agr="dummy3" xmlns:spec1="dummy4">
<ns:manageWorkItemRequest>
<ns:wiFocus>
<act:orderDate>2020-03-16T10:30:56.000Z</act:orderDate>
<act:orderItem>
<agr:instance>
<spec1:customerServiceIdentifier>ETHA15302121</spec1:customerServiceIdentifier>
<spec1:instanceCharacteristic>
<spec1:action>
<spec1:code>Modify</spec1:code>
</spec1:action>
<spec1:instanceIdentifier>
<spec1:value>OS014-AHEFV5T9</spec1:value>
</spec1:instanceIdentifier>
</spec1:instanceCharacteristic>
</agr:instance>
</act:orderItem>
<act:orderVersion>1</act:orderVersion>
</ns:wiFocus>
<ns:wiAction>Create</ns:wiAction>
<ns:wiVersion>1</ns:wiVersion>
</ns:manageWorkItemRequest>
</root>';
--the query
WITH AllNamespaces As
(
SELECT CONCAT('ns',ROW_NUMBER() OVER(ORDER BY (B.namespaceUri))) Prefix
,B.namespaceUri
FROM #xml.nodes('//*') A(nd)
CROSS APPLY(VALUES(A.nd.value('namespace-uri(.)','nvarchar(max)')))B(namespaceUri)
WHERE LEN(B.namespaceUri)>0
GROUP BY B.namespaceUri
)
,recCte AS
(
SELECT 1 AS NestLevel
,ROW_NUMBER() OVER(ORDER BY A.nd) AS ElementPosition
,CAST(REPLACE(STR(ROW_NUMBER() OVER(ORDER BY A.nd),5),' ','0') AS VARCHAR(900)) COLLATE DATABASE_DEFAULT AS SortString
,CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)')) ORDER BY A.nd),']') AS FullName
,CAST(CONCAT('/',ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)')) ORDER BY A.nd),']') AS NVARCHAR(MAX)) COLLATE DATABASE_DEFAULT AS XPath
,A.nd.value('text()[1]','nvarchar(max)') AS NodeValue
,A.nd.query('./*') NextFragment
FROM #xml.nodes('/*') A(nd)
LEFT JOIN AllNamespaces ns ON ns.namespaceUri=A.nd.value('namespace-uri(.)','nvarchar(max)')
UNION ALL
SELECT r.NestLevel+1
,ROW_NUMBER() OVER(ORDER BY A.nd)
,CAST(CONCAT(r.SortString,REPLACE(STR(ROW_NUMBER() OVER(ORDER BY A.nd),5),' ','0')) AS VARCHAR(900)) COLLATE DATABASE_DEFAULT
,CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)')) ORDER BY A.nd),']') AS FullName
,CONCAT(r.XPath,'/',ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)')) ORDER BY A.nd),']') AS FullName
,A.nd.value('text()[1]','nvarchar(max)') AS NodeValue
,A.nd.query('./*') NextFragment
FROM recCte r
CROSS APPLY NextFragment.nodes('*') A(nd)
OUTER APPLY(SELECT Prefix FROM AllNamespaces ns WHERE ns.namespaceUri=A.nd.value('namespace-uri(.)','nvarchar(max)')) ns
)
SELECT XPath
,NodeValue
,NestLevel
,ElementPosition
,SortString
FROM recCte
--WHERE NodeValue IS NOT NULL
ORDER BY SortString;
--The result
/*
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| XPath | NodeValue | NestLevel | ElementPosition | SortString |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderDate[1] | 2020-03-16T10:30:56.000Z | 4 | 1 | 00001000010000100001 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:customerServiceIdentifier[1] | ETHA15302121 | 6 | 1 | 000010000100001000020000100001 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:action[1]/ns4:code[1] | Modify | 8 | 1 | 0000100001000010000200001000020000100001 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:instanceIdentifier[1]/ns4:value[1] | OS014-AHEFV5T9 | 8 | 1 | 0000100001000010000200001000020000200001 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderVersion[1] | 1 | 4 | 3 | 00001000010000100003 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiAction[1] | Create | 3 | 2 | 000010000100002 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
| /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiVersion[1] | 1 | 3 | 3 | 000010000100003 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+-----------+-----------------+------------------------------------------+
*/
--just to show, that the created XPath is working as expected:
WITH XMLNAMESPACES('dummy1' AS ns1,'dummy2' AS ns2,'dummy3' AS ns3,'dummy4' AS ns4,'dummy5' AS ns5)
SELECT #xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderDate[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:customerServiceIdentifier[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:action[1]/ns4:code[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:instanceIdentifier[1]/ns4:value[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderVersion[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiAction[1]','nvarchar(max)')
,#xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiVersion[1]','nvarchar(max)');
The idea in short:
The namespace prefixes can be defined by your own. The underlying URI is important.
The first cte will create a set of all occuring URIs and return this together with a prefix.
The recursive CTE will traverse deeper and deeper into the XML. This will continue as long as APPLY with .nodes() can return nested nodes.
The full name is concatenated as well as the full XPath.
The CASTs and COLLATEs help to avoid data type mismatch (recursive CTEs are very picky with this).
The concatenated SortString is needed to ensure the same order in your output.
UPDATE: You might think about FROM OPENXML
Just to mention it: There is the absolutely outdated FROM OPENXML, which is - afaik - the only way to get literally everything back:
DECLARE #xml XML=
N'<root xmlns="default" xmlns:ns="dummy">
<a ns:test="blah">blub</a>
<ns:b test2="hugo">blubber</ns:b>
</root>';
DECLARE #DocHandle INT;
EXEC sp_xml_preparedocument #DocHandle OUTPUT, #xml;
SELECT * FROm OPENXML(#DocHandle,'/*');
EXEC sp_xml_removedocument #DocHandle;
the result
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| id | parentid | nodetype | localname | prefix | namespaceuri | datatype | prev | text |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 0 | NULL | 1 | root | NULL | default | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 2 | 0 | 2 | xmlns | xmlns | NULL | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 10 | 2 | 3 | #text | NULL | NULL | NULL | NULL | default |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 3 | 0 | 2 | ns | xmlns | NULL | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 11 | 3 | 3 | #text | NULL | NULL | NULL | NULL | dummy |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 4 | 0 | 1 | a | NULL | default | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 5 | 4 | 2 | test | ns | dummy | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 12 | 5 | 3 | #text | NULL | NULL | NULL | NULL | blah |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 6 | 4 | 3 | #text | NULL | NULL | NULL | NULL | blub |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 7 | 0 | 1 | b | ns | dummy | NULL | 4 | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 8 | 7 | 2 | test2 | NULL | NULL | NULL | NULL | NULL |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 13 | 8 | 3 | #text | NULL | NULL | NULL | NULL | hugo |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
| 9 | 7 | 3 | #text | NULL | NULL | NULL | NULL | blubber |
+----+----------+----------+-----------+--------+--------------+----------+------+---------+
As you can see, this result contains namespaces, prefixes and content. But it is very clumsy and far away from "today" :-)

Find the period of occurence of a value in table

I have a table with the following data.
+------------+---------+
| Date | Version |
+------------+---------+
| 1/10/2019 | 1 |
| .... | |
| 15/10/2019 | 1 |
| 16/10/2019 | 2 |
| .... | |
| 26/10/2019 | 2 |
| 27/10/2019 | 1 |
| .... | |
| 30/10/2019 | 1 |
+------------+---------+
I need to find the period of occurrence for version in the table.
Eg:Suppose I need to get Version 1 occurence details which is present from 1/10/2019 to 15/10/2019 and from 27/10/2019 to 30/10/2019. How can i query the database for such a result?
I have tried many ways but not able to produce the desired result .I even doubt this is possible using a query!
Any inputs are highly appreciated.
Expected output:
+---------+-------------+-------------+
| Version | Period from | Period To |
+---------+-------------+-------------+
| 1 | 1/10/2019 | 15/10/2019 |
| 2 | 16/10/2019 | 26/10/2019 |
| 1 | 27/10/2019 | 30/10/2019 |
+---------+-------------+-------------+
This is gaps and Islands question.
Try this
DECLARE #SampleData TABLE ( [Date] DATE, [Version] INT)
INSERT INTO #SampleData ([Date], [Version])
VALUES
('01-10-2019', 1), ('02-10-2019', 1), ('15-10-2019', 1),
('16-10-2019', 2), ('17-10-2019', 2),('26-10-2019', 2),
('27-10-2019', 1), ('28-10-2019', 1), ('30-10-2019', 1)
SELECT
Y.[Version]
,PeriodFrom = MIN(Y.[Date])
,PeriodTo = MAX(Y.[Date])
FROM(
SELECT
X.[Version]
,X.[Date]
,ISLAND = RN-ROW_NUMBER()OVER( PARTITION BY X.[Version] ORDER BY X.[Date])
FROM(
SELECT
RN=ROW_NUMBER()OVER( ORDER BY S.[Date])
,S.[Date]
,S.[Version]
FROM
#SampleData S
) X
) Y
GROUP BY
Y.[Version], Y.ISLAND
ORDER BY
PeriodFrom
Output
Version PeriodFrom PeriodTo
1 2019-10-01 2019-10-15
2 2019-10-16 2019-10-26
1 2019-10-27 2019-10-30

Couldn't use SELECT in including Unicode characters table SQL

I used Bulk Insert to import data from a text:
BULK INSERT dbo.Infosp1 FROM 'D:\test.txt' WITH ( FIELDTERMINATOR =',', ROWTERMINATOR ='\n', DATAFILETYPE='widechar')
This is my 'D:\test.txt'(saved by Endcoding : Unicode ):
BácHồng,Giá,3
BácHồng,Hành,2
BácHồng,Lơxanh,3
BácHồng,Xả,3
BácHồng,Ngao,5
BácHồng,Bắptàu,5
CôHòaBính,Giá,5
CôHòaBính,Càrốt,2
CôHòaBính,Chanh,2
---->This is my table. Click to show image
Why using INSERT shows 0 result??????:
SELECT * FROM dbo.Infosp1 WHERE Khach = 'BácHồng'
or
SELECT * FROM dbo.Infosp1 WHERE Khach = 'CôHòaBính'
---I think that have some problems around convertion data type because save this 'D:\test.txt' by Endcoding : ANSI have some errors like :
BácH?ng, CôH?aBính. In other case, when my field didn't error type i could use SELECT to show all results. I want have a solve could make it work.
Try prepending N to unicode string literals in SQL Server:
SELECT * FROM dbo.Infosp1 WHERE Khach = N'BácHồng'
and
SELECT * FROM dbo.Infosp1 WHERE Khach = N'CôHòaBính'
Example:
create table Infosp1 (Khach nvarchar(64), FirstName nvarchar(64), SomeNumber int)
insert into Infosp1 values
(N'BácHồng',N'Giá',3)
,(N'BácHồng',N'Hành',2)
,(N'BácHồng',N'Lơxanh',3)
,(N'BácHồng',N'Xả',3)
,(N'BácHồng',N'Ngao',5)
,(N'BácHồng',N'Bắptàu',5)
,(N'CôHòaBính',N'Giá',5)
,(N'CôHòaBính',N'Càrốt',2)
,(N'CôHòaBính',N'Chanh',2)
SELECT 'WithN' as WithOrWithoutN, * FROM dbo.Infosp1 WHERE Khach = N'BácHồng'
union all
SELECT 'WithoutN',* FROM dbo.Infosp1 WHERE Khach = 'BácHồng'
union all
SELECT 'WithN', * FROM dbo.Infosp1 WHERE Khach = N'CôHòaBính'
union all
SELECT 'WithoutN',* FROM dbo.Infosp1 WHERE Khach = 'CôHòaBính'
rextester demo: http://rextester.com/WSNNX6950
returns:
+----------------+-----------+-----------+------------+
| WithOrWithoutN | Khach | FirstName | SomeNumber |
+----------------+-----------+-----------+------------+
| WithN | BácHồng | Giá | 3 |
| WithN | BácHồng | Hành | 2 |
| WithN | BácHồng | Lơxanh | 3 |
| WithN | BácHồng | Xả | 3 |
| WithN | BácHồng | Ngao | 5 |
| WithN | BácHồng | Bắptàu | 5 |
| WithN | CôHòaBính | Giá | 5 |
| WithN | CôHòaBính | Càrốt | 2 |
| WithN | CôHòaBính | Chanh | 2 |
| WithoutN | CôHòaBính | Giá | 5 |
| WithoutN | CôHòaBính | Càrốt | 2 |
| WithoutN | CôHòaBính | Chanh | 2 |
+----------------+-----------+-----------+------------+

How to get a child table records which exist in results of a table valued function

I have a table named TBL_WorkOrder as below :
+----+------------+----------------+
| Id | SystemCode | WorkOrderTitle |
+----+------------+----------------+
| 1 | C001 | Title 1 |
| 2 | C002 | Title 2 |
| 3 | C003 | Title 3 |
+----+------------+----------------+
and another table named TBL_WorkGroup
+----+---------------+
| Id | WorkGroupName |
+----+---------------+
| 1 | WorkGroup1 |
| 2 | WorkGroup2 |
| 3 | WorkGroup3 |
+----+---------------+
Each work order can contain different work groups as below (TBL_WorkOrderGroup)
+----+-------------+-------------+
| Id | WorkOrderId | WorkGroupId |
+----+-------------+-------------+
| 1 | 1 | 1 |
| 2 | 1 | 3 |
| 3 | 2 | 1 |
+----+-------------+-------------+
The problem is that I send a varchar string like '1,3' to the stored procedure. This varchar is changed to a table using a table valued function. I want to obtain the work orders that contain both '1' and '3' as their work groups.
What should i do in this case?
DECLARE #String VARCHAR(100) = '1,3'
;WITH Split AS
(
SELECT SUBSTRING(#String,0,CHARINDEX(',',#String)) SplitStr,SUBSTRING(#String,CHARINDEX(',',#String)+1,LEN(#String)) RemainStr
UNION ALL
SELECT CASE WHEN CHARINDEX(',',RemainStr) = 0 THEN RemainStr ELSE SUBSTRING(RemainStr,0,CHARINDEX(',',RemainStr)) END,
CASE WHEN CHARINDEX(',',RemainStr) = 0 THEN '' ELSE SUBSTRING(RemainStr,CHARINDEX(',',RemainStr)+1,LEN(RemainStr)) END
FROM Split
WHERE ISNULL(RemainStr,'') <> ''
)
SELECT SplitStr FROM Split

How to Create Pivot in MS Access to avoid null values for one type of record?

Can anyone please help me in creating the below pivot table in MS-Access.
Data table
value | Rank | Type
1.5 | 5 | alpha
2.4 | 4 | alpha
3.6 | 3 | alpha
4.63 | 2 | alpha
5.36 | 1 | alpha
Required Pivot is
Type | 5 | 4 | 3 | 2 | 1
alpha|1.5 |2.4 |3.6 |4.63 |5.36
I have tried the below query
TRANSFORM [Value]
SELECT [Type]
FROM tbl
GROUP BY [Type], [Value]
PIVOT [Rank];
and getting resultset as
Type | 1 | 2 | 3 | 4 | 5
alpha| | | | |1.5
alpha| | | |2.4|
alpha| | |3.6| |
alpha| |4.63| | |
alpha|5.36| | | |
Could anyone please help me in updating this query to get the required result.
Thanks a ton.
Honey
To get all "alpha" values in one row, you must remove Value from the GROUP BY section.
Then you need an aggregation function for it - if you are sure to have only one value per rank, First() does the job.
To get the 5-4-3-2-1 order, add an ORDER BY clause.
TRANSFORM First([Value])
SELECT [Type]
FROM tPivot
GROUP BY [Type]
ORDER BY [Rank] DESC
PIVOT [Rank];
Edit: it works for multiple Types
+-------+-----+-----+-----+------+------+
| Type | 5 | 4 | 3 | 2 | 1 |
+-------+-----+-----+-----+------+------+
| alpha | 1,5 | 2,4 | 3,6 | | 5,36 |
| beta | 999 | | | 4,63 | 66 |
+-------+-----+-----+-----+------+------+
CREATE TABLE #A
(
value NUMERIC(22,6), Rank INT, Type VARCHAR(10)
)
INSERT INTO #A VALUES
(1.5, 5,'alpha'),
(2.4,4,'alpha'),
(3.6,3,'alpha'),
(4.63,2,'alpha'),
(5.36,1,'alpha')
SELECT [5],[4],[3],[2],[1]
FROM
(select value,RANK,TYPE from #A ) AS SourceTable
PIVOT
(
MAX(value)
FOR RANK IN ([1],[2],[3],[4],[5])
) AS PivotTable;