Hi,
I have a hive table with following columns
partid string, store string and location array in table, values are save in this order
part123, store123, location
[{"position":1,"price":124.0,"card_pos":"External","clicked":0},
{"position":2,"price":94.78,"card_pos":"Cbox","clicked":0},
{"position":3,"price":94.77,"card_pos":"External","clicked":0}]
>
I can see values of arry in one line which is fine, I would also like to
see values from partid, store, location values in this way.
>
+---------+-----+----------+--------+-----------+----------+
partid |store | position | price | card_pos | clicked |
+---------+-----+----------+--------+-----------+----------+
part123|store123| 1 | 124.0 | External | 0 |
part123|store123| 2 | 94.78 | Cbox | 0 |
part123|store123| 3 | 94.77 | External | 0 |
+---------+-----+----------+----------+----------+---------+
>
So far I can only see array values by using inline function in this way.
select inline(location) as (position, price, card_pos, clicked) from table;
>+---------+--------+-----------+----------+
| position | price | card_pos | clicked |
+----------+--------+-----------+----------+
| 1 | 124.0 | External | 0 |
| 2 | 94.78 | Cbox | 0 |
| 3 | 94.77 | External | 0 |
+----------+----------+----------+---------+
>
Use lateral view in conjunction with inline and select the other columns.
select partid,store,t.position,t.price,t.card_pos,t.clicked
from table
lateral view inline(location) t as position, price, card_pos, clicked
Edit: Per OP's request to handle cases when the array column is null, use lateral view outer option.
select partid,store,t.position,t.price,t.card_pos,t.clicked
from table
lateral view outer inline(location) t as position, price, card_pos, clicked
Related
I have a table of arrays, and would like to return a list of items.
| table |
|---------------------------------------|
| [{"item": 1},{"item": 2},{"item": 3}] |
| [{"item": 4},{"item": 5},{"item": 6}] |
| [{"item": 7},{"item": 8},{"item": 9}] |
Example Query
The following method will return a wide table of items, but it doesn't scale well.
select
json_value([table], '$[0].item'),
json_value([table], '$[1].item'),
json_value([table], '$[2].item')
from someTable;
How can I select properties of arrays of indeterminate size? (like 100)
Desired Output
| items |
|-------|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
You need to use OPENJSON to achieve this. Also, as I note, you should choose a different name than Table for a column's name. TABLE is a reserved key word and it's confusing as a COLUMN is not a TABLE.
WITH VTE AS(
SELECT *
FROM (VALUES(N'[{"item": 1},{"item": 2},{"item": 3}]'),
(N'[{"item": 4},{"item": 5},{"item": 6}]'),
(N'[{"item": 7},{"item": 8},{"item": 9}]'))V([Table])) --Table isn't a good choice of a came for a column.
--TABLE is a reserved keyword.
SELECT T.item
FROM VTE V
CROSS APPLY OPENJSON(V.[Table]) --Table isn't a good choice of a came for a column. TABLE is a reserved keyword.
WITH(item int) T;
I am trying to add two values together that are associated to two different rows that have different names values. I would normally adds the values using the group function, however the group function only works for matching strings.
| Direction | | Total |
------------+--+--------
| Test1 | | 5000 |
| Test2 | | 3000 |
| Test3 | | 2000 |
Expected outcome (adding Test1 + Test2) while keeping Test 3 in the table:
| Direction | | Total |
--------------+--+--------
| Test1plus2 | | 8000 |
| Test3 | | 2000 |
You would use a conditional expression:
select (case when direction in ('test1', 'test2') then 'test1plus2'
else direction
end) as direction_group,
sum(total) as total
from t
group by direction_group;
I want to get data in a single row from two tables which have one to many relation.
Primary table
Secondary table
I know that for each record of primary table secondary table can have maximum 10 rows. Here is structure of the table
Primary Table
-------------------------------------------------
| ImportRecordId | Summary |
--------------------------------------------------
| 1 | Imported Successfully |
| 2 | Failed |
| 3 | Imported Successfully |
-------------------------------------------------
Secondary table
------------------------------------------------------
| ImportRecordId | CodeName | CodeValue |
-------------------------------------------------------
| 1 | ABC | 123456A |
| 1 | DEF | 8766339 |
| 1 | GHI | 887790H |
------------------------------------------------------
I want to write a query with inner join to get data from both table in a way that from secondary table each row should be treated as column instead showing as multiple row.
I can hard code 20 columns names(as maximum 10 records can exist in secondary table and i want to display values of two columns in a single row) so if there are less than 10 records in the secondary table all other columns will be show as null.
Here is expected Output. You can see that for first record in primary table there was only three rows that's why two required columns from these three rows are converted into columns and for all others columns values are null.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| ImportRecordId | Summary | CodeName1 | CodeValue1 | CodeName2 | CodeValue2 | CodeName3 | CodeValue3 | CodeName4 | CodeValue4| CodeName5 | CodeValue5| CodeName6 | CodeValue6| CodeName7 | CodeValue7 | CodeName8 | CodeValue8 | CodeName9 | CodeValue9 | CodeName10 | CodeValue10|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | Imported Successfully | ABC | 123456A | DEF | 8766339 | GHI | 887790H | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here is my simple SQL query which return all data from both tables but instead multiple rows from secondary table i want to get them in a single row like above result set.
Select p.ImportRecordId,p.Summary,s.*
from [dbo].[primary_table] p
inner join [dbo].[secondary_table] s on p.ImportRecordId = s.ImportRecordId
The following uses Row_Number(), a JOIN and a CROSS APPLY to create the source of the PIVOT
You'll have to add the CodeName/Value 4...10
Example
Select *
From (
Select A.[ImportRecordId]
,B.Summary
,C.*
From (
Select *
,RN = Row_Number() over (Partition by [ImportRecordId] Order by [CodeName])
From Secondary A
) A
Join Primary B on A.[ImportRecordId]=B.[ImportRecordId]
Cross Apply (values (concat('CodeName' ,RN),CodeName)
,(concat('CodeValue',RN),CodeValue)
) C(Item,Value)
) src
Pivot (max(value) for Item in (CodeName1,CodeValue1,CodeName2,CodeValue2,CodeName3,CodeValue3) ) pvt
Returns
ImportRecordId Summary CodeName1 CodeValue1 CodeName2 CodeValue2 CodeName3 CodeValue3
1 Imported Successfully ABC 123456A DEF 8766339 GHI 887790H
I am writing a query that pulls 50 fields from 12 sub-queries in the FROM statement. Each sub query is left-joined on two fields the Item SKU and Brand ID. However there is one table where the Brand ID is concatenated in a comma delimited column.
My problem is that I am having trouble parsing this column so that I can use it as a foreign key to join to the other sub-queries. I tried setting the column = to a variable and then using the String_Split function, but was getting the error 'No column selected for column 1' in the query. If anyone has any suggestions of how to parse this data into a NEW row so that SKU that has multiple brands associated to it each has a row showing that SKU and Brand. I have added a screen shot of the data that needs to be parsed. Thanks!
Isn't this example on the MSSQL docs exactly what you're trying to do?
+-----------+--------------------+----------------------------+
| ProductId | Name | Tags |
+-----------+--------------------+----------------------------+
| 1 | Full-Finger Gloves | clothing,road,touring,bike |
| 2 | LL Headset | bike |
| 3 | HL Mountain Frame | bike,mountain |
+-----------+--------------------+----------------------------+
gets transformed into (note the change in the column name!)
+-----------+--------------------+----------+
| ProductId | Name | value |
+-----------+--------------------+----------+
| 1 | Full-Finger Gloves | clothing |
| 1 | Full-Finger Gloves | road |
| 1 | Full-Finger Gloves | touring |
| 1 | Full-Finger Gloves | bike |
| 2 | LL Headset | bike |
| 3 | HL Mountain Frame | bike |
| 3 | HL Mountain Frame | mountain |
+-----------+--------------------+----------+
using
SELECT ProductId, Name, value
FROM Product
CROSS APPLY STRING_SPLIT(Tags, ',');
Since you didn't share any code, it's impossible for me to be more specific... but this example really seems to me should be the piece you're missing.
I have a dataset which looks like so
ID | PName | Node | Val |
1 | Tag | Name | XBA |
2 | Tag | Desc | Dec1 |
3 | Tag | unit | Int |
6 | Tag | tids | 100 |
7 | Tag | post | AAA |
1 | Tag | Name | XBB |
2 | Tag | Desc | Des9 |
3 | Tag | unit | Float |
7 | Tag | post | BBB |
6 | Tag | tids | 150 |
I would like the result in my report to be
Name | Desc | Unit | Tids | Post |
XBA | Dec1 | int | 100 | AAA |
XBB | Des9 | Float | 150 | BBB |
I have tried using a SSRS Matrix with
Row: PName
Data: Node
Value: Val
The results were simply one row with Name and next row with desc and next with unit etc. Its not all in the same rows and also the second row was missing. This is possibly because there is no grouping on the dataset.
What is a good way of achieving the expected results?
I would not recommend this for a production scenario but if you need to knock out a report quickly or something you can try this. I would just not feel comfortable that the order of the records you get will always be what you expect.
You COULD try to insert the results of the SP into a table (regular table, temp table, table variable...doesn't matter really as long as you can get an identity column added). Assuming that the rows always come out in the correct order (which is probably not a valid assumption 100% of the time) then add an identity column on the table to get a unique row number for each row. From there you should be able to write some math logic to "group" your values together and then pivot out what you want.
create table #temp (ID int, PName varchar(100), Node varhar(100), Val varchar(100))
insert #temp exec (your stored proc)
alter table #temp add UniqueID int identity
then use UniqueID (modulo on 5 perhaps?) to group records together and then pivot