I want to make a sum on field created using different columns of my table so I have make 2 nested SELECT.
My nested SELECT works good alone, but when I put it inside the other one I show errors and I can't find them out
I've tested my nested SELECT and it works.
DECLARE #Debut datetime ='2019-03-18'
DECLARE #Fin datetime = '2019-03-31'
SELECT Secteur,
Site_Theo,
Techno,
SUM(Trafic) as Trafic_Hebdo
FROM (
SELECT [TRAFIC_VOIX_HEBDO].Trafic_voix as Trafic ,
[INFO_CELL_N].SITE_THEO,
[INFO_CELL_N].TECHNO,
CONCAT('A' , right(SITE_THEO,5) , REPLACE( REPLACE( REPLACE( right([TRAFIC_VOIX_HEBDO].Cellname, 1) , 'D' , 'A' ) , 'E' , 'B' ) , 'F' , 'C' ) ) as Secteur
FROM [KIWI].[dbo].[TRAFIC_VOIX_HEBDO] INNER JOIN [KIWI].[dbo].[INFO_CELL_N]
ON [KIWI].[dbo].[TRAFIC_VOIX_HEBDO].Cellname = [KIWI].[dbo].[INFO_CELL_N].CELLNAME
WHERE ( right([TRAFIC_VOIX_HEBDO].cellname,1)='A' OR
right([TRAFIC_VOIX_HEBDO].cellname,1)='B' OR
right([TRAFIC_VOIX_HEBDO].cellname,1)='C' OR
right([TRAFIC_VOIX_HEBDO].cellname,1)='D' OR
right([TRAFIC_VOIX_HEBDO].cellname,1)='E' OR
right([TRAFIC_VOIX_HEBDO].cellname,1)='F' )
AND ( [TRAFIC_VOIX_HEBDO].TSTAMP BETWEEN #Debut AND #Fin )
)
GROUP BY Secteur, Site_Teho, Techno
Error Message:
Msg 156, Level 15, State 1, Line 34 Incorrect syntax near the keyword
'GROUP'.
I would like to understand why I have errors.
To me the code looks good
Give a ALIAS to you sub query as -
SELECT ....
FROM (
SELECT...
)A -- A is the alias
GROUP BY Secteur, Site_Teho, Techno
Secondly, you can write your WHERE as below-
WHERE RIGHT([TRAFIC_VOIX_HEBDO].cellname, 1) IN ( 'A','B','C','D','E','F')
AND [TRAFIC_VOIX_HEBDO].TSTAMP BETWEEN #Debut AND #Fin
A derived table must have a name - provide it immediately after the closing parenthesis and before "group by ".
select Secteur,
...
from ( SELECT [TRAFIC_VOIX_HEBDO].Trafic_voix as Trafic ,
...
) as usefulnamehere
group by Secteur, Site_Teho, Techno
order by ...;
Related
User #psaraj12 helped me with a ticket here about finding ascii character in a string in my DB with the following code:
with test (col) as (
select
'L.A.D'
from
dual
union all
select
'L..D.'
from
dual
)
select
col,
case when max(ascii_of_one_character) >= 65535 then 'NOT OK' else 'OK' end result
from
(
select
col,
substr(col, column_value, 1) one_character,
ascii(
substr(col, column_value, 1)
) ascii_of_one_character
from
test cross
join table(
cast(
multiset(
select
level
from
dual connect by level <= length(col)
) as sys.odcinumberlist
)
)
)
group by
col
having max(ascii_of_one_character) >= 4000000000;
The script looks for characters of a certain range GROUPs them and marks displays them.
Is it possible to include this in a REPLACE statement of a similar sort:
REPLACE(table.column, max(ascii_of_one_character) >= 4000000000, '')
EDIT: As per #flyaround answer this is the code I use changed a little bit:
with test (col) as (
select skunden.name1
from skunden
)
select col
, REGEXP_REPLACE(col, 'max(ascii_of_one_character)>=4000000000', '') as cleaned
, CASE WHEN REGEXP_COUNT(col, 'max(ascii_of_one_character)>=4000000000') > 0 THEN 0 ELSE 1 END as isOk
from test;
Coming back to your original code, because my suggested REGEX_REPLACE is not working sufficient with high surrogates. Your approach is already very effective, so I jumped into it to have a solution here.
MERGE
INTO skunden
USING (
select
id as innerId,
name as innerName,
case when max(ascii_of_one_character) >= 65535 then 0 else 1 end isOk,
listagg(case when ascii_of_one_character <65535 then one_character end , '') within group (order by rn) as cleaned
from
(
select
id,
name,
substr(name, column_value, 1) one_character,
ascii(
substr(name, column_value, 1)
) ascii_of_one_character
, rownum as rn
from
skunden cross
join table(
cast(
multiset(
select
level
from
dual connect by level <= length(name)
) as sys.odcinumberlist
)
)
)
group by
id, name
having max(ascii_of_one_character) >= 4000000000
)
ON (skunden.id = innerId)
WHEN MATCHED THEN
UPDATE
SET name = cleaned
;
On MERGE you can't use the referencing column for an update. Therefore you should use the unique key (I used 'id' in my example) of your table.
The resulting value will be 'L..D' for your example value of 'L..D.'
If I got your question correctly you would like to remove characters with a higher decimal representation of characters than specified.
You could check to use REGEXP_REPLACE for this, like:
with test (col) as (
select
'L.A.D'
from
dual
union all
select
'L..D.'
from
dual
)
select col
, REGEXP_REPLACE(col, '[^\u00010000-\u0010FFFF]+$', '') as cleaned
, CASE WHEN REGEXP_COUNT(col, '[^\u00010000-\u0010FFFF]+$') > 0 THEN 0 ELSE 1 END as isOk
from test;
I want the title for the SQL query.How Can I generate it? In the following code ContractID is int, Contract Number is nvarchar and ClientContractNumber is nvarchar.
I have tried the following Code
SELECT *
INTO #temp
FROM
(SELECT ContractID,ContractNumber, ClientContractNumber
FROM dbo.bsContract
WHERE ContractNumber = 'CR6359-V1') t
SELECT 'Title',' ',' '
UNION ALL
SELECT 'ContractID', 'ContractNumber', 'ClientContractNumber'
UNION ALL
SELECT *
FROM #temp
DROP TABLE #temp
The following error occurs:
Msg 245, Level 16, State 1, Line 7
Conversion failed when converting the varchar value 'Title' to data type int.
The expected output SHOULD BE:
Title
ContactID ContractNumber ClientContractNumber
----------------------------------------------------
6368 cr1234 newContract
use cast for ContractID
SELECT 'Title',' ',' '
UNION ALL
SELECT 'ContractID','ContractNumber','ClientContractNumber'
UNION ALL
SELECT cast( ContractID as varchar(50)),ContractNumber, FROM #temp
DROP TABLE #temp
You need to cast the contract ID to varchar before unioning since union requires all the datatypes to match.
Edit:
SELECT * INTO #temp FROM (SELECT cast(ContractID as varchar) ContractID,ContractNumber,ClientContractNumber
FROM dbo.bsContract WHERE ContractNumber='CR6359-V1') t
SELECT 'Title' ContractID,' ' ContractNumber,' ' ContractNumber
UNION ALL
SELECT 'ContractID' ContractID,'ContractNumber' ContractNumber,'ClientContractNumber' ContractNumber
UNION ALL
SELECT * FROM #temp
DROP TABLE #temp
I am trying to use multiple pivot in a single query on same column.
Since i am using same column "month" for all the pivot's, i have added column header to the select list and have added different alias name. Month column has int datatype value. Below is the code:
Select * FROM
(
SELECT
[team],
Count_O,
Count_Of_OA,
Avg,
[month]+ '_a' as month_a,
[month] + '_b' as month_b,
[users]
FROM [#Temp]
) AS X
PIVOT
(
MAX(Count_OA)
FOR [month_a] IN ([4_a], [5_a], [6_b])
) AS PivotTable1
PIVOT
(
MAX(Count_O)
FOR [month_b] IN ([4_b], [5_b], [6_b])
) AS PivotTable2
When i execute this, I get the below error:
Msg 8114, Level 16, State 1, Line 44
Error converting data type nvarchar to int.
Any inputs would be much appreciated.
Try this
Select * FROM
(
SELECT
[team],
Count_O,
Count_Of_OA,
Avg,
Convert(varchar(max),[month])+ '_a' as month_a,
Convert(varchar(max),[month]) + '_b' as month_b,
[users]
FROM [#Temp]
) AS X
PIVOT
(
MAX(Count_OA)
FOR [month_a] IN ([4_a], [5_a], [6_b])
) AS PivotTable1
PIVOT
(
MAX(Count_O)
FOR [month_b] IN ([4_b], [5_b], [6_b])
) AS PivotTable2
I have
;with cte as
(
select rn=1, name = CAST('name'as varchar(50))
union all
select rn+1, CAST(name as varchar(50))+ CAST( (rn+1) as varchar(50))
from cte where rn<100)
select * from cte
error
Msg 240, Level 16, State 1, Line 1
Types don't match between the anchor and the recursive part in column "name" of recursive query "cte".
Try something like
;with cte as
(
select rn=1,
name = CAST('name'as varchar(100))
union all
select rn+1,
CAST(name as varchar(50))+ CAST( (rn+1) as varchar(50))
from cte where rn<100)
select * from cte
You have to remember that all fields in the anchor and the recursive part have to be of the same type. That also goes for varchar fields.
I am trying to create a delimitted string from the results of a query in DB2 on the iSeries (AS/400). I've done this in T-SQL, but can't find a way to do it here.
Here is my code in T-SQL. I'm looking for an equivelant in DB2.
DECLARE #a VARCHAR(1000)
SELECT #a = COALESCE(#a + ', ' + [Description], [Description])
FROM AP.Checkbooks
SELECT #a
If the descriptions in my table look like this:
Desc 1
Desc 2
Desc 3
Then it will return this:
Desc 1, Desc 2, Desc 3
Essentially you're looking for the equivalent of MySQL's GROUP_CONCAT aggregate function in DB2. According to one thread I found, you can mimic this behaviour by going through the XMLAGG function:
create table t1 (num int, color varchar(10));
insert into t1 values (1,'red'), (1,'black'), (2,'red'), (2,'yellow'), (2,'green');
select num,
substr( xmlserialize( xmlagg( xmltext( concat( ', ', color ) ) ) as varchar( 1024 ) ), 3 )
from t1
group by num;
This would return
1 red,black
2 red,yellow,green
(or should, if I'm reading things correctly)
You can do this using common table expressions (CTEs) and recursion.
with
cte1 as
(select description, row_number() over() as row_nbr from checkbooks),
cte2 (list, cnt, cnt_max) AS
(SELECT VARCHAR('', 32000), 0, count(description) FROM cte1
UNION ALL
SELECT
-- No comma before the first description
case when cte2.list = '' THEN RTRIM(CHAR(cte1.description))
else cte2.list || ', ' || RTRIM(CHAR(cte1.description)) end,
cte2.cnt + 1,
cte2.cnt_max
FROM cte1,cte2
WHERE cte1.row_nbr = cte2.cnt + 1 AND cte2.cnt < cte2.cnt_max ),
cte3 as
(select list from cte2
where cte2.cnt = cte2.cnt_max fetch first 1 row only)
select list from cte3;
I'm trying to do this in OLEDB and from what I understand you can't do this because you can't do anything fancy in SQL for OLEDB like declare variables or create a table. So I guess there is no way.
If you are running DB2 9.7 or higher, you can use LISTAGG function. Have a look here:
http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.sql.ref.doc%2Fdoc%2Fr0058709.html