How to make a start writing this CTE in SQL Server? - sql

I have a table which contains data of different elements in a database. This is a count of all elements in the database (which is restored daily, so no DDL/DML triggers possible)
Table looks like this:
LogDate SYSTEM_TABLE VIEW SQL_TABLE_VALUED_FUNCTION DEFAULT_CONSTRAINT SQL_STORED_PROCEDURE RULE FOREIGN_KEY_CONSTRAINT SERVICE_QUEUE SQL_INLINE_TABLE_VALUED_FUNCTION CHECK_CONSTRAINT USER_TABLE PRIMARY_KEY_CONSTRAINT INTERNAL_TABLE TYPE_TABLE SQL_TRIGGER SQL_SCALAR_FUNCTION UNIQUE_CONSTRAINT
20150204 45 253 60 1401 5259 2 784 3 4 95 2141 1604 26 4 16 195 33
20150203 45 253 60 1401 5259 2 784 3 4 95 2141 1604 16 4 16 195 33
20150202 45 253 60 1401 5259 2 784 3 4 95 2141 1604 21 4 16 195 33
20150201 45 253 60 1401 5259 2 784 3 4 95 2141 1604 25 4 16 195 33
20150131 45 253 60 1401 5259 2 784 3 4 95 2141 1604 21 4 16 195 33
What I would like to do is compare the most recent log date (20150204) with the previous logdate (20150203) and see if there are any changes between the elements. This will then fire off an email to the relevant developer for them to investigate (but this section isn't important at hte moment, just highlighting the changes between the logdates for now)
ETA:
It's part of a much larger query that uses temp tables etc:
IF OBJECT_ID('tempdb..#DBTotsTEMP') is not null drop table #DBTotsTEMP
--declare variables
DECLARE #DynamicPivotQuery as NVARCHAR(MAX)
DECLARE #ColumnName as NVARCHAR(MAX)
SELECT RIGHT(date, 4) + RIGHT(LEFT(date, 5), 2) + LEFT(date, 2) AS LogDate, [count] as CNT, type_desc
INTO [#DBTotsTEMP]
FROM BI_STG.SSRS.MH_DB_Totals
ORDER BY LogDate DESC
SELECT #ColumnName= ISNULL(#ColumnName + ',', '') + QUOTENAME([type_desc])
FROM (
SELECT DISTINCT [type_desc] FROM #DBTotsTEMP) as TypeDescs
SET #DynamicPivotQuery =
N'SELECT LogDate, ' + #ColumnName + '
INTO #MH_DB_Totals
FROM #DBTotsTEMP
PIVOT (SUM([CNT])
FOR [type_desc] in (' + #ColumnName + ')) as PVTTable
ORDER BY LogDate desc
select * from #MH_DB_Totals'
EXEC sp_executesql #DynamicPivotQuery
and I've got no idea where the CTE part should go, or how to highlight changes in the figures!

Sorted it, used a SELECT INTO with the IDENTITY function to add in row numbers then joined temp table back to itself on rowid = rowid-1.

Related

Insert value refer to other column

Here is original table A
Currency
DM_LS
ProductID
TimeID
TWD
1
26
559
TWD
1
26
560
TWD
1
27
561
TWD
2
27
562
TWD
2
28
563
TWD
2
28
564
I would like to generate serial number from table A above. So I add new column named SerialNum
Now I have no idea how to generate and insert the value. Value is Currency + DM_LS + ProductID + TimeID
Does it work through SQL?
Desired Result
Currency
DM_LS
ProductID
TimeID
SerialNum
TWD
1
26
559
TWD126559
TWD
1
26
560
TWD126560
TWD
1
27
561
TWD127561
TWD
2
27
562
TWD227562
TWD
2
28
563
TWD228563
TWD
2
28
564
TWD228564
Thanks so much.
You can do it two ways:
Add computed column
ALTER TABLE TABLEA ADD SerialNum AS CONCAT(Currency, DM_LS, Productid, TimeID)
Add separate column
ALTER TABLE TABLEA ADD SerialNum VARCHAR(200);
UPDATE TABLEA
SET SerialNum = CONCAT(Currency, DM_LS, Productid, TimeID)
It is simply an UPDATE statement with concatenation on the columns.
You need to esnure each column is CAST to a common datatype - VARCHAR in this case - and then just use the format ``col1 + col2 + ...etc```

Identifying unicode character in nvarchar column in SQL Server

I have a table called airports in a SQL Server database, with a column declared as nvarchar(255). I had to declare it as nvarchar otherwise SSIS failed to import the data from a .csv file generated by an API.
I have approx 25k records in this table, where by from what I can tell 763 have Unicode characters in them, by running this query:
select cast(name as varchar), name
from airports
where cast(name as varchar) <> name
The first row shows the following two values returned in column 1 and 2
Harrisburg Capital City Airpor
Harrisburg Capital City Airport
The first value from column 1 has had the last t stripped off it, which I assume means there is one unicode character in the string. Please let me know if I am wrong, as I am a bit useless with unicode characters.
My question is: how can I find the unicode characters in the column, and is there a safe / recommended way to remove them?
I did try this to see if I could find it, but it didn't do what I thought it would do.
set nocount on
DECLARE #nstring NVARCHAR(100)
SET #nstring =(select name from airports where fs = 'HAR')
DECLARE #position INT
SET #position = 1
DECLARE #CharList TABLE (Position INT,UnicodeChar NVARCHAR(1),UnicodeValue INT)
WHILE #position <= DATALENGTH(#nstring)
BEGIN
INSERT #CharList
SELECT
#position as Position,
CONVERT(nchar(1),SUBSTRING(#nstring, #position, 1)) as UnicodeChar,
UNICODE(SUBSTRING(#nstring, #position, 1)) as UnicodeValue
SET #position = #position + 1
END
SELECT *
FROM #CharList[/sql]
ORDER BY unicodevalue
The output is as follows
32 NULL
33 NULL
34 NULL
35 NULL
36 NULL
37 NULL
38 NULL
39 NULL
40 NULL
41 NULL
42 NULL
43 NULL
44 NULL
45 NULL
46 NULL
47 NULL
48 NULL
49 NULL
50 NULL
51 NULL
52 NULL
53 NULL
54 NULL
55 NULL
56 NULL
57 NULL
58 NULL
59 NULL
60 NULL
61 NULL
62 NULL
11 32
19 32
24 32
25 A 65
20 C 67
12 C 67
1 H 72
2 a 97
13 a 97
17 a 97
7 b 98
10 g 103
15 i 105
5 i 105
21 i 105
26 i 105
18 l 108
29 o 111
28 p 112
14 p 112
9 r 114
3 r 114
4 r 114
30 r 114
27 r 114
6 s 115
16 t 116
22 t 116
31 t 116
8 u 117
23 y 121
However, if you want to first find the records which have some unicode chars then follow below approach with help of case expression
;WITH CTE
AS (
SELECT DATA,
CASE
WHEN(CAST(DATA AS VARCHAR(MAX)) COLLATE SQL_Latin1_General_Cp1251_CS_AS) = DATA
THEN 0
ELSE 1
END HasUnicodeChars,
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) RN
FROM <table_name>)
SELECT * FROM CTE where HasUnicodeChars = 1

Calculate Sub Query Column Based On Calculated Column

I have a table ScheduleRotationDetail that contains these as columns:
ScheduleRotationID ScheduleID Ordinal Duration
379 61 1 1
379 379 2 20
379 512 3 1
379 89 4 20
I have a query that goes like this in order to get the day of the year each schedule is supposed to start on:
SELECT ScheduleID, Ordinal, Duration,
,Duration * 7 AS DurationDays
,( SELECT ( ISNULL( SUM(ISNULL( Duration, 0 )), 0 ) - 1 ) * 7
FROM ScheduleRotationDetail WHERE ScheduleRotationID = srd.ScheduleRotationID
AND Ordinal <= srd.Ordinal ) AS StartDay
FROM ScheduleRotationDetail srd
WHERE srd.ScheduleRotationID = 379
That outputs this as the result set:
ScheduleID Ordinal Duration DurationDays StartDay
61 1 1 7 0
379 2 20 140 140
512 3 1 7 147
89 4 20 140 287
Yet what I need the start day column values to be are:
0
7
147
154
I have tried CTEs but can't get it to work so I've come to here for advice.
It looks like you want a cumulative sum. In SQL Server 2012+, you can do:
SELECT ScheduleID, Ordinal, Duration,
SUM(Duration*7) OVER (ORDER BY Ordinal) - Duration*7 as StartDate
FROM ScheduleRotationDetail srd ;
In earlier versions, you can use APPLY for this purpose (or a correlated subquery).

Pivot table multiple column values in a single column

I've got a table like that,
id PID VID Type PriceA PriceB
41 297 2 128 70.000 80.000
42 297 3 256 90.000 100.000
43 297 4 300 110.000 120.000
44 297 5 400 130.000 140.000
45 294 2 128 10.000 50.000
46 294 3 256 20.000 60.000
47 294 4 300 30.000 70.000
48 294 5 400 40.000 80.000
49 294 6 450 50.000 85.000
50 294 7 470 45.000 75.000
What I want to do is a query with PID parameter and get a result like that
PID | 128 | 256 | 300 | 400
297 | 70.000 / 80.0000 | 90.000 / 100.000 | 110.000 / 120.000 | 130.000 / 140.000
I have tried several different options pivot table subquery etc., but I could not make it.
This is full working exmaple:
CREATE TABLE DataSource
(
[ID] TINYINT
,[PID] SMALLINT
,[VID] TINYINT
,[Type] SMALLINT
,[PriceA] VARCHAR(32)
,[PriceB] VARCHAR(32)
)
INSERT INTO DataSource ([ID],[PID],[VID],[Type],[PriceA],[PriceB])
VALUES (41,297,2,128,70.000,80.000)
,(42,297,3,256,90.000,100.000)
,(43,297,4,300,110.000,120.000)
,(44,297,5,400,130.000,140.000)
,(45,294,2,128,10.000,50.000)
,(46,294,3,256,20.000,60.000)
,(47,294,4,300,30.000,70.000)
,(48,294,5,400,40.000,80.000)
,(49,294,6,450,50.000,85.000)
,(50,294,7,470,45.000,75.000)
SELECT *
FROM
(
SELECT [PID]
,[Type]
,[PriceA] + ' / ' + [PriceB] AS [Price]
FROM DataSource
) AS DataSource
PIVOT
(
MAX([Price]) FOR [Type] IN ([128],[256],[300],[400],[450], [470])
) PVT
The output is like this:
The idea is to build the column [PriceA] + ' / ' + [PriceB] and then to make the pivot.
Note, that I have hardcoded the posible [Type] values. If you need to make this dynamic you can build a dynamic PIVOT building the SQL string and then executing it with sp_executesql procedure like is done here.

Create a dynamic table based on existing table result in sql [duplicate]

This question already has answers here:
SQL Server 2008 Vertical data to Horizontal
(5 answers)
Closed 9 years ago.
This is the actual table.
Month RCount Cond_Id Cond_desc
Jan-13 52 -1 N/A
Jan-13 194 0 NORMAL
Jan-13 86 2 ABNORMAL
Feb-13 54 -1 N/A
Feb-13 158 0 NORMAL
Feb-13 110 2 ABNORMAL
Mar-13 14 -1 N/A
Mar-13 113 0 NORMAL
Mar-13 90 2 ABNORMAL
Apr-13 3 -1 N/A
Apr-13 259 0 NORMAL
Apr-13 144 2 ABNORMAL
May-13 10 -1 N/A
May-13 693 0 NORMAL
May-13 305 2 ABNORMAL
May-13 1 4 CRITICAL
Jun-13 169 0 NORMAL
Jun-13 36 2 ABNORMAL
Jun-13 1 4 CRITICAL
I need the following results.
R_id Cond_Id Cond_desc Jan-13 Feb-13 Mar-13 Apr-13 May-13 Jun-13
1 -1 N/A 51 54 14 3 10 169
2 0 NORMAL 194 158 113 259 693 36
3 2 ABNORMAL 86 110 90 144 305 1
4 0 CRITICAL 0 0 0 0 1 0
Assuming that you wont this:
Sum the values of rcount grouped by month.
The value of COND_ID in your example is wrong, for example for the case CRITICAL the value should be 4.
The field R_ID (rownumber) is only a count of the query.
The following query maybe will be useful:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME([MONTH])
from MYTABLE
group by [MONTH]
order by [MONTH]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ROW_NUMBER() over (order by COND_ID) AS R_ID,COND_ID,COND_DESC,' + #cols + '
from
(
SELECT
COND_ID,
COND_DESC,
rcount,
MONTH
FROM MYTABLE
) x
pivot
(
sum(rcount)
for [MONTH] in (' + #cols + ')
) p '
execute sp_executesql #query;
Here you try this sql fiddle.
This query I've created from the bluefeet's link.