I have created an table with complex data type array in hive. The query is
create table testivr (
mobNo string,
callTime string,
refNo int,
callCat string,
menus array <string>,
endType string,
duration int,
transferNode string
)
row format delimited
fields terminated by ','
collection items terminated by '|'
The records loaded are like
9220276765 2011-05-01 21:26:45 29 E ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:4","M477:3","M005:2","M090:5","M465:9"] RAT 218 TR716
Now I need to check whether the first two fields of array are:
PRE_HOST10_JINGLE_PPPREF_WELCOME_PP-PREF_PROMO_PP and M001.
I tried using:
select * where menu[0] = "val1" and menu[1] = "val2"`
and also like
menu(0) = "val1" and menu(1) = "val2"
I'm getting an error like:
SemanticException [Error 10011]: Line 3:0 Invalid function 'menus'
How to compare them?
if the val1 and val2 are hardcoded value
val1 = "PRE_HOST10_JINGLE_PPPREF_WELCOME_PP-PREF_PROMO_PP"
val2 = 'M001'
you may try to convert array to string and use substr to find expect value
--sample records
with testivr as (
select '9220276765' as mobNo
, '2011-05-01 21:26:45' as callTime
, 29 as refNo
, 'E' as callCat
, array("PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:4","M477:3","M005:2","M090:5","M465:9") as menus
, 'RAT' as endType
, 218 as duration
, 'TR716' as transferNode
union all
select '9220276766'
, '2011-05-02 21:26:45'
, 30
, 'E'
, array("PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:5","M478:4","M006:3","M091:5","M465:10")
, 'RAT'
, 219
, 'TR717'
union all
select '9220276767'
, '2011-05-03 21:26:45'
, 31
, 'E'
, array("PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M002:5","M478:4","M006:3","M091:5","M465:10")
, 'RAT'
, 220
, 'TR718'
)
select mobno,refno,menus
from testivr t
where substr(concat_ws(',',menus),1,50) = 'PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP'
and substr(concat_ws(',',menus),52,4) = 'M001'
;
Temp Table testivr:
+-------------+----------------------+----------+------------+-------------------------------------------------------------------------------------------------------+------------+-------------+-----------------+--+
| t.mobno | t.calltime | t.refno | t.callcat | t.menus | t.endtype | t.duration | t.transfernode |
+-------------+----------------------+----------+------------+-------------------------------------------------------------------------------------------------------+------------+-------------+-----------------+--+
| 9220276765 | 2011-05-01 21:26:45 | 29 | E | ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:4","M477:3","M005:2","M090:5","M465:9"] | RAT | 218 | TR716 |
| 9220276766 | 2011-05-02 21:26:45 | 30 | E | ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:5","M478:4","M006:3","M091:5","M465:10"] | RAT | 219 | TR717 |
| 9220276767 | 2011-05-03 21:26:45 | 31 | E | ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M002:5","M478:4","M006:3","M091:5","M465:10"] | RAT | 220 | TR718 |
+-------------+----------------------+----------+------------+-------------------------------------------------------------------------------------------------------+------------+-------------+-----------------+--+
Query results:
+-------------+--------+-------------------------------------------------------------------------------------------------------+--+
| mobno | refno | menus |
+-------------+--------+-------------------------------------------------------------------------------------------------------+--+
| 9220276765 | 29 | ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:4","M477:3","M005:2","M090:5","M465:9"] |
| 9220276766 | 30 | ["PRE_HOST10_JINGLE_PP-PREF_WELCOME_PP-PREF_PROMO_PP","M001:5","M478:4","M006:3","M091:5","M465:10"] |
+-------------+--------+-------------------------------------------------------------------------------------------------------+--+
Related
column Name: employee_number
values: 256749,358976,583546
want ouput as 579,596,856
how can i do this? irrespective of length or datatype?
Working code:
WITH src AS (
SELECT *
FROM VALUES (256749),(358976),(583546) AS t(employee_number)
)
SELECT src.employee_number, LISTAGG(s.VALUE, '') AS ouput
FROM src,
TABLE(SPLIT_TO_TABLE(REGEXP_REPLACE(employee_number::string, '.', ',\\0', 2), ',')) AS s
WHERE s.INDEX % 2 = 0
GROUP BY src.employee_number, s.SEQ;
Result:
+------------------+--------+
| EMPLOYEE_NUMBER | OUTPUT |
+------------------+--------+
| 358976 | 596 |
| 256749 | 579 |
| 583546 | 856 |
+------------------+--------+
I want to join 2 tables such that I get the NAR for every combination of Type and BillingID where it exists.
Where a BillingID doesn't have a certain Type, then either NULL or 0 is returned for the NAR along with the Type and BillingID.
Is something like this even possible using SQL?
A simplified version of my data is shown below:
Type list:
+----------+
| Type |
+----------+
| NEW |
| CHNG |
| LAP |
+----------+
Data:
+----------+-----------+-----+
| Type | BillingID | NAR |
+----------+-----------+-----+
| NEW | ABC | 5 |
| CHNG | ABC | 15 |
| LAP | ABC | 10 |
| CHNG | DEF | 20 |
+----------+-----------+-----+
Desired result:
+----------+-----------+-----+
| Type | BillingID | NAR |
+----------+-----------+-----+
| NEW | ABC | 5 |
| CHNG | ABC | 15 |
| LAP | ABC | 10 |
| CHNG | DEF | 20 |
| NEW | DEF | 0 |
| LAP | DEF | 0 |
+----------+-----------+-----+
The last 2 rows are what is causing me problems.
I think you can do it like this:
declare #table table (type1 varchar(5))
insert into #table
values
('new'),
('chng'),
('lap')
declare #table2 table (typeid varchar(5),billingid varchar(5),nar int)
insert into #table2
values
( 'NEW', 'ABC', 5 ),
( 'CHNG' , 'ABC', 15 ),
( 'LAP' , 'ABC', 10 ),
( 'CHNG' , 'DEF', 20 )
select Z.*,case when c.nar IS null then 0 else c.nar end as nar from (
select * from #table a
outer apply (select distinct billingid from #table2 b ) p
)Z
left join #table2 c on Z.type1 = c.typeid and Z.billingid = c.billingid
order by billingid
Result
I have a table named tableX structed like this. Notice the relation of childNo and parentNo columns.
childNo | parentNo |locationId |value
--------+----------+-----------+--------+
26 | NULL | 7 | value1 |
27 | NULL | 7 | value2 |
28 | 27 | 7 | value3 |
29 | 27 | 7 | value4 |
30 | 27 | 7 | value5 |
34 | NULL | 7 | value6 |
and I want to copy the same value column information to a different locationId(let's say locationId = 3) with new childNo and parentNo (protecting the relation)
Expected output.
childNo | parentNo |locationId |value
--------+----------+-----------+--------+
36 | NULL | 3 | value1 |
37 | NULL | 3 | value2 |
38 | 37 | 3 | value3 |
39 | 37 | 3 | value4 |
40 | 37 | 3 | value5 |
44 | NULL | 3 | value6 |
How can I achieve that using T-SQL?
Perhaps I'm missing something, but you could just do:
insert into t(childNo, parentNo, locationId, value)
select t.childNo + 10, t.ParentNo + 10, 3, t.value
from t
where t.locationId = 7;
I try this sample in SQL Server 2012.
DECLARE #lastParent int;
DECLARE #lastChild int;
DECLARE #newLocationId int;
SET #newLocationId = 3;
SELECT #lastParent = MAX(ParentNo) FROM tableX WHERE ParentNo IS NOT NULL;
SELECT #lastChild = MAX(ChildNo) from tableX;
INSERT INTO tableX (childNo, parentNo , LocationId, valueColumn)
SELECT
#lastChild + ROW_NUMBER() OVER (PARTITION BY LocationId ORDER BY childNo) AS childNo,
CASE WHEN (ParentNo IS NOT NULL) then #lastParent + 1
ELSE ParentNo
END as NewParentNo,
#NewLocationId as NewLocationId, valueColumn
FROM tableX
WHERE LocationId = 7
ORDER BY childNo
Two instances of this code running at same time, can produce duplicates values. I think your table must have Unique constraint on childNo and some trigger to validate parentNo
I'm having a serious problem with one of my import tables. I've imported an Excel file to a SQL Server table. The table ImportExcelFile now looks like this (simplified):
+----------+-------------------+-----------+------------+--------+--------+-----+---------+
| ImportId | Excelfile | SheetName | Field1 | Field2 | Field3 | ... | Field10 |
+----------+-------------------+-----------+------------+--------+--------+-----+---------+
| 1 | C:\Temp\Test.xlsx | Sheet1 | Age / Year | 2010 | 2011 | | 2018 |
| 2 | C:\Temp\Test.xlsx | Sheet1 | 0 | Value1 | Value2 | | Value9 |
| 3 | C:\Temp\Test.xlsx | Sheet1 | 1 | Value1 | Value2 | | Value9 |
| 4 | C:\Temp\Test.xlsx | Sheet1 | 2 | Value1 | Value2 | | Value9 |
| 5 | C:\Temp\Test.xlsx | Sheet1 | 3 | Value1 | Value2 | | Value9 |
| 6 | C:\Temp\Test.xlsx | Sheet1 | 4 | Value1 | Value2 | | Value9 |
| 7 | C:\Temp\Test.xlsx | Sheet1 | 5 | NULL | NULL | | NULL |
+----------+-------------------+-----------+------------+--------+--------+-----+---------+
I now want to insert those values from Field1 to Field10 to the table AgeYear(in my original table there are about 70 columns and 120 rows). The first row (Age / Year, 2010, 2011, ...) is the header row. The column Field1 is the leading column. I want to save the values in the following format:
+-----------+-----+------+--------+
| SheetName | Age | Year | Value |
+-----------+-----+------+--------+
| Sheet1 | 0 | 2010 | Value1 |
| Sheet1 | 0 | 2011 | Value2 |
| ... | ... | ... | ... |
| Sheet1 | 0 | 2018 | Value9 |
| Sheet1 | 1 | 2010 | Value1 |
| Sheet1 | 1 | 2011 | Value2 |
| ... | ... | ... | ... |
| Sheet1 | 1 | 2018 | Value9 |
| ... | ... | ... | ... |
+-----------+-----+------+--------+
I've tried the following query:
DECLARE #sql NVARCHAR(MAX) =
';WITH cte AS
(
SELECT i.SheetName,
ROW_NUMBER() OVER(PARTITION BY i.SheetName ORDER BY i.SheetName) AS rn,
' + #columns + ' -- #columns = 'Field1, Field2, Field3, Field4, ...'
FROM dbo.ImportExcelFile i
WHERE i.Sheetname LIKE ''Sheet1''
)
SELECT SheetName,
age Age,
y.[Year]
FROM cte
CROSS APPLY
(
SELECT Field1 age
FROM dbo.ImportExcelFile
WHERE SheetName LIKE ''Sheet1''
AND ISNUMERIC(Field1) = 1
) a (age)
UNPIVOT
(
[Year] FOR [Years] IN (' + #columns + ')
) y
WHERE rn = 1'
EXEC (#sql)
So far I'm getting the desired ages and years. My problem is that I don't know how I could get the values. With UNPIVOT I don't get the NULL values. Instead it fills the whole table with the same values even if they are NULL in the source table.
Could you please help me?
Perhaps an alternative approach. This is not dynamic, but with the help of a CROSS APPLY and a JOIN...
The drawback is that you'll have to define the 70 fields.
Example
;with cte0 as (
Select A.ImportId
,A.SheetName
,Age = A.Field1
,B.*
From ImportExcelFile A
Cross Apply ( values ('Field2',Field2)
,('Field3',Field3)
,('Field10',Field10)
) B (Item,Value)
)
,cte1 as ( Select * from cte0 where ImportId=1 )
Select A.SheetName
,[Age] = try_convert(int,A.Age)
,[Year] = try_convert(int,B.Value)
,[Value] = A.Value
From cte0 A
Join cte1 B on A.Item=B.Item
Where A.ImportId>1
Returns
I am having some difficulty trying to achieve some data in MSSQL. Here what I have:
SO_ID | SO_DATE | WAGE_A | WAGE_B | WAGE_B_DUR |
1 | 12/12/06| 100 | 200 | 15 |
2 | 10/10/06| 150 | 250 | 10 |
What I want :
SO_ID | SO_DATE | WAGE_TYPE | AMOUNT | DURATION |
1 | 12/12/06| WAGE_A | 100 | NULL |
1 | 12/12/06| WAGE_B | 200 | 15 |
2 | 10/10/06| WAGE_B | 250 | 10 |
2 | 10/10/06| WAGE_A | 150 | NULL |
I really appreciate it if you could give me some help or advice (including change the first table).
Try as:
CREATE TABLE try_val(SO_ID int, SO_DATE int, WAGE_A int, WAGE_B int, WAGE_B_DUR int)
insert into try_val values (1 , 12/12/06, 100 , 200 , 15 )
insert into try_val values (2 , 10/10/06, 150 , 250 , 10 )
select SO_ID,SO_DATE,'WAGE_A' AS WAGE_TYPE,WAGE_A AS AMOUNT,NULL AS DURATION from try_val
UNION ALL
select SO_ID,SO_DATE,'WAGE_B' AS WAGE_TYPE,WAGE_A AS AMOUNT,WAGE_B_DUR AS DURATION from try_val
ORDER BY SO_ID
You can use a simple SELECT with UNION ALL as follows
select
SO_ID,
SO_DATE,
WAGE_TYPE = 'WAGE_A',
AMOUNT = WAGE_A,
DURATION = WAGE_B_DUR
from myData
union all
select
SO_ID,
SO_DATE,
WAGE_TYPE = 'WAGE_B',
AMOUNT = WAGE_B,
DURATION = WAGE_B_DUR
from myData
order by SO_ID