Cross tab (Pivot) query in SQL - sql-server-2008

I am using a pivot query in SQL as below:
SELECT classification, [BSL] AS BSL, [AQ] AS AQ, [KYN] AS KYN, ([BSL] + [AQ] +
[KYN]) AS CR_TTL
FROM
(
SELECT classification, Shed
FROM PunctualityMain WHERE Date >= '4/1/2012' AND Date <= '6/30/2012'
) x
PIVOT
(
COUNT(Shed)
FOR Shed IN ([BSL], [AQ], [KYN])) p ">
In result i am getting 0 in null cells, is it possible to show null in place of 0 in result page?

the simplest solution would be to use the NULLIF shortcut, like so:
SELECT classification
, NULLIF([BSL],0) AS BSL
, NULLIF([AQ],0) AS AQ
, NULLIF([KYN],0) AS KYN
, NULLIF([BSL] + [AQ] + [KYN],0) AS CR_TTL
FROM
(
SELECT classification, Shed
FROM PunctualityMain WHERE Date >= '4/1/2012' AND Date <= '6/30/2012'
) x
PIVOT
(
COUNT(Shed)
FOR Shed IN ([BSL], [AQ], [KYN])) p

Related

Teradata SQL Split Single String into Table Rows

I have one string element, for example : "(1111, Tem1), (0000, Tem2)" and hope to generate a data table such as
var1
var2
1111
Tem1
0000
Tem2
This is my code, I created the lag token and filter with odd rows element.
with var_ as (
select '(1111, Tem1), (0000, Tem2)' as pattern_
)
select tbb1.*, tbb2.result_string as result_string_previous
from(
select tb1.*,
min(token) over(partition by 1 order by token asc rows between 1 preceding and 1 preceding) as min_token
from
table (
strtok_split_to_table(1, var_.pattern_, '(), ')
returns (outkey INTEGER, token INTEGER, result_string varchar(20))
) as tb1) tbb1
inner join (select min_token, result_string from tbb1) tbb2
on tbb1.token = tbb2.min_token
where (token mod 2) = 0;
But it seems that i can't generate new variables in "from" step and applied it directly in "join" step.
so I wanna ask is still possible to get the result what i want in my procedure? or is there any suggestion?
Thanks for all your assistance.
I wouldn't split / recombine the groups. Split each group to a row, then split the values within the row, e.g.
with var_ as (
select '(1111, Tem1), (0000, Tem2)' as pattern_
),
split1 as (
select trim(leading '(' from result_string) as string_
from
table ( /* split at & remove right parenthesis */
regexp_split_to_table(1, var_.pattern_, '\)((, )|$)','c')
returns (outkey INTEGER, token_nbr INTEGER, result_string varchar(256))
) as tb1
)
select *
from table(
csvld(split1.string_, ',', '"')
returns (var1 VARCHAR(16), var2 VARCHAR(16))
) as tb2
;

Sort MySQL results by a column with several values separated by a period

I suspect this may have already been asked, but I'm not sure how to phrase the question so that SO search engine picks it up.
I have a column called TCID, which contains values in this format:
1.A.1.1.1
4.A.1.1.1
2.B.1.1.10
2.B.1.1.2
...
There are 5 units in this TCID, separated by periods. I want the position to the left to take the highest priority, and then finally the last digit is the lowest priority.
So it would sort like this:
1.A.1.1.1
2.B.1.1.2
2.B.1.1.10
4.A.1.1.1
Here is the query I have so far. It almost works, but the last position is not getting sorted.
SELECT *
FROM system
WHERE cluster = \"$tc_name\"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED)
Can anyone help me fix this or suggest a better way to do this?
There are obviously better ways to store this information in the database, such as storing the values in separate fields. However, it's not always possible to change the code base to do such things.
But I believe you just need to add the final order by to your query in order to for it to work as expected;
SELECT *
FROM system
WHERE cluster = "<some search term>"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',5) , LENGTH( SUBSTRING_INDEX(tcid,'.',4)) + 2 ) AS UNSIGNED);
Please see this sqlfiddle to check
Just for fun...
SELECT *
FROM
(
SELECT '1.A.1.1.1' x
UNION ALL
SELECT '4.A.1.1.1'
UNION ALL
SELECT '2.B.1.1.10'
UNION ALL
SELECT '2.B.1.1.2'
) a
ORDER BY
INET_ATON(CONCAT(MID(x,1,1),MID(x,4,1000)));

SSIS Package -Count based on multiple columns

I need to create an SSIS Package that provides me the count of workdoneby (contractor/company).
Input table from sql server db:
I need to count no of orders by contractor and company for a particular day + station + worktype + accountno.
My output should look like this.
Can someone help me how to create a package to get the desired output?
Since the data is in a table, you can ask the database engine to do the calculation logic.
Setup
I created a temporary table and populated it with the supplied data.
CREATE TABLE
#Source
(
[Date] date
, Station char(3)
, worktype char(2)
, Accountno varchar(10)
, workdoneby varchar(10)
)
INSERT INTO
#Source
(
Date
, Station
, worktype
, Accountno
, workdoneby
)
VALUES
('2018-06-24', 'RMS', 'RH', 'I.145.001', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.001', 'Contractor')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Company')
, ('2018-06-24', 'RMS', 'PH', 'I.145.002', 'Contractor');
Query time
Now let's query! I find it is helpful to break these problems down into smaller pieces. The first thing I want to do is break out the workdoneby column into two columns with a 1 or 0
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
Running that let's me look at the results and see I still have 4 rows and I get the correct entity counted.
The next step is to collapse/summarize/roll-up the values. You indicate we should group by date/station/worktype/accountno so that's exactly what we're going to to do.
I find it easier to debug if I take that first query and make it a derived table so the basic form now becomes SELECT * FROM (ORIGINAL QUERY HERE) AS D thus
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, D.contractorCount
, D.companyCount
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
Now that you can see it's giving the same original results, we're going to use the SUM function on the contractorCount and companyCount columns and GROUP BY date/station/worktype/accountno
SELECT
D.Date
, D.Station
, D.worktype
, D.Accountno
, SUM(D.contractorCount) AS contractor
, SUM(D.companyCount) AS company
FROM
(
SELECT
S.Date
, S.Station
, S.worktype
, S.Accountno
, CASE S.workdoneby
WHEN 'Contractor' THEN 1
ELSE 0
END AS contractorCount
, CASE S.workdoneby
WHEN 'Company' THEN 1
ELSE 0
END AS companyCount
FROM
#Source AS S
) D
GROUP BY
D.Date
, D.Station
, D.worktype
, D.Accountno;
SSIS
Now that we have data looking as expected, within SSIS you need to do something with it. Your question doesn't specify what you need to do but likely you're going to use a Data Flow Task to push this aggregated data from one place to another destination (different server, Excel, etc) or you're going to push this data into a table on the same server in which case you're going to use an Execute SQL Task

How to get previous month data in MDX

I am trying to get previous month data for my SSRS report.But i am not getting any result.Could you please give any help.Below is my query.
SELECT
NON EMPTY
{[Measures].[Trade Net Amount]} ON COLUMNS
,NON EMPTY
{
[Fund].[Fund Name].[Fund Name].ALLMEMBERS*
[Transaction Type].[Transaction Description].[Transaction Description].ALLMEMBERS*
[Calendar Day].[Year].[Year].ALLMEMBERS*
[Calendar Day].[Month].[Month].ALLMEMBERS
}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM
(
--FROM ( SELECT ( STRTOSET(#CalendarDayMonth, CONSTRAINED) ) ON COLUMNS
--FROM ( SELECT ( STRTOSET(#CalendarDayYear, CONSTRAINED) ) ON COLUMNS
SELECT
StrToMember
(
"[Calendar Day].[Calender Hierarchy].[Month].[" + Format(Now(),"yyyy")
+
Format
(
Now()
,"MMM"
)
+ "].PrevMember"
) ON COLUMNS
FROM [Escher_Hybrid]
);

MySQL issue with NULL values

I have a table with fields: country_code, short_name, currency_unit, a2010, a2011, a2012, a2013, a2014, a2015. a2010-a2015 fields are type of double.
How do I make a query which orders the results by average of fields a2010-a2015, keeping in mind that these fields might have NULL value?
I tried this code and it did not work (returns a mistake, which tells there is something wrong in ORDER BY part. mistake was saying something about coumn names and GROUP BY). The logic is: ORDER BY ((A)/(B)) where A - sum of not NULL fields and B - count of not NULL fields.
Any ideas?
(if important, the code is going to be used in BigInsights environment)
SELECT country_code, short_name, currency_unit, a2010, a2011, a2012,
a2013, a2014, a2015
FROM my_schema.my_table
WHERE Indicator_Code = 'SE.PRM.TENR'
ORDER BY
(
(
Coalesce(a2010,0) + Coalesce(a2011,0) + Coalesce(a2012,0)
+Coalesce(a2013,0) + Coalesce(a2014,0) + Coalesce(a2015,0)
)
/
(
COUNT(Coalesce(a2010)) + COUNT(Coalesce(a2011)) + COUNT(Coalesce(a2012))
+ COUNT(Coalesce(a2013)) + COUNT(Coalesce(a2014)) +
COUNT(Coalesce(a2015))
)
) DESC;
use MySQL ifnull
IFNULL(expression_1,expression_2)
in your query :-
IFNULL(
(
COUNT(Coalesce(a2010)) + COUNT(Coalesce(a2011)) + COUNT(Coalesce(a2012))
+ COUNT(Coalesce(a2013)) + COUNT(Coalesce(a2014)) +
COUNT(Coalesce(a2015))
),
1
)