Show data in a-b format in sql server 2008 - sql-server

I am using SQL Server 2008.
I have a table which has distinct numbers i.e int data type. Now I need a query which shows data in increasing order in the format cast(a as varchar)+'-'cast(b as varchar) i.e a-b where a is the smallest number which has yet not been shown and b is subsequently the next smallest number.
I know that SQL Server 2012 has the lead function which would make this question moot but how do I do that on sql server 2008?

CREATE TABLE #nr(nr INT); INSERT INTO #nr(nr)VALUES(9),(7),(1),(2),(25),(33),(10),(3);
SELECT
CAST(n_o.nr AS VARCHAR)+'-'+CAST((SELECT MIN(n_i.nr) FROM #nr AS n_i WHERE n_i.nr>n_o.nr) AS VARCHAR)
FROM
#nr AS n_o
WHERE
(SELECT MIN(n_i.nr) FROM #nr AS n_i WHERE n_i.nr>n_o.nr) IS NOT NULL
ORDER BY
nr;
DROP TABLE #nr;
Results in:
╔══════════════════╗
║ (No column name) ║
╠══════════════════╣
║ 1-2 ║
║ 2-3 ║
║ 3-7 ║
║ 7-9 ║
║ 9-10 ║
║ 10-25 ║
║ 25-33 ║
╚══════════════════╝

Related

dynamic sql embedded in select query

I have a table Users,
╔════╦═══════╦══════╗
║ Id ║ Name ║ Db ║
╠════╬═══════╬══════╣
║ 1 ║ Peter ║ DB1 ║
║ 2 ║ John ║ DB16 ║
║ 3 ║ Alex ║ DB23 ║
╚════╩═══════╩══════╝
and many databases that have the same structure (Same tables, same procedures, ...), so every database have a table named Project, and this is the structure of Project table,
╔════╦═════════╦═════════════╗
║ Id ║ Request ║ Information ║
╠════╬═════════╬═════════════╣
║ 1 ║ 126 ║ XB1 ║
║ 2 ║ 126 ║ D6 ║
║ 3 ║ 202 ║ BM-23 ║
╚════╩═════════╩═════════════╝
So, when I query a database :
SELECT count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB1].[dbo].[Project]
I get this result :
╔═════════════╗
║ NbrRequests ║
╠═════════════╣
║ 2 ║
╚═════════════╝
Now, what I want is to "link"/"join" ... results from the table Users to this query, where the column Db in Users table is the name of my database, so I can get a result like this :
╔════╦═══════╦══════╦═════════════╗
║ Id ║ Name ║ Db ║ NbrRequests ║
╠════╬═══════╬══════╬═════════════╣
║ 1 ║ Peter ║ DB1 ║ 2 ║
║ 2 ║ John ║ DB16 ║ 3 ║
║ 3 ║ Alex ║ DB23 ║ 6 ║
╚════╩═══════╩══════╩═════════════╝
I'm trying with dynamic SQL, but no luck.
NB : Every user has only one database, and a database belong to only one user, it's one-to-one relationship
The way you can do it is with a UNION counting every specific database table and giving it a identification for the database, like this:
SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests
FROM [Users] u INNER JOIN
(SELECT 'DB1' as db, count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB1].[dbo].[Project]
UNION
SELECT 'DB16', count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB16].[dbo].[Project]
UNION
SELECT 'DB23', count(distinct([Request])) as nbrRequests
FROM [SRV02].[DB23].[dbo].[Project]
) dbCts ON u.Db = dbCts.db
Don't forget to add the server and schema to the Users table I didn't because there is no such info on your question.
Also in order to do this, your connected user must have privileges on all databases.
Dynamic SQL can be very tricky.
This example builds the select query from the users table. The variable #Query is incremented for each line returned by the Users table. Each row returns a query that joins the local users table to the projects table in a remote db. The results of each query are UNIONED together.
Example
-- Wil holds our dynamic query.
DECLARE #Query NVARCHAR(MAX) = '';
-- Builds our dynamic statement.
SELECT
#Query =
#Query
+ CASE WHEN LEN(#Query) > 0 THEN ' UNION ALL ' ELSE '' END
+ 'SELECT u.Id, u.Name, u.Db, COUNT(DISTINCT p.Request) AS NbrRequest '
+ 'FROM [SVR02].' + QUOTENAME(DB) + 'dbo.Project AS p INNER JOIN Users u ON u.Db= p.Db '
+ 'GROUP BY u.Id, u.Name, u.Db'
FROM
Users
;
-- Executes the dynamic statement.
EXECUTE (#Query);
This example uses QUOTENAME to help avoid SQL injection attacks.
Combining these 2 answers https://stackoverflow.com/a/35795690/1460399 and https://stackoverflow.com/a/35795189/1460399, I got this solution :
DECLARE #Query NVARCHAR(MAX)= 'SELECT u.Id, u.Name, u.Db, dbCts.nbrRequests FROM [Users] u INNER JOIN (';
DECLARE #QueryLength INT= LEN(#Query);
SELECT #Query = #Query
+CASE WHEN LEN(#Query) > #QueryLength THEN ' UNION ' ELSE '' END
+'SELECT '''+Db+''' as db, count(distinct(Request)) as nbrRequests FROM [SRV02].'+Db+'[Project]'
FROM Users;
SET #Query = #Query+') dbCts ON u.Db = dbCts.db';
EXECUTE (#Query);

Audit Microsoft SQL Server table with many columns

I have a problem with getting this audit to work on my table.
I have a table with 197 columns, and i want to audit that. We have used this solution successfully before but the tables always had lesser columns.
The solution i have implemented is from this url at the bottom.
It just seems like it has something to do with that my table has so many columns. Does anyone have any input about this at all?
Pop Rivett SQL Server Audit
I have two ideas too many columns vs wrong ordinal position.
The code in link is from 2006. So it was written for SQL Server 2005. Based on COLUMNS_UPDATED():
The ORDINAL_POSITION column of the INFORMATION_SCHEMA.COLUMNS view is
not compatible with the bit pattern of columns returned by
COLUMNS_UPDATED.
To obtain a bit pattern compatible with
COLUMNS_UPDATED, reference the ColumnID property of the COLUMNPROPERTY
system function when you query the INFORMATION_SCHEMA.COLUMNS view.
CREATE TABLE tab(id INT, col1 INT, col2 INT, col3 INT,
col4 INT, col5 INT, col6 INT, col7 INT, col8 INT);
ALTER TABLE tab DROP COLUMN col1;
ALTER TABLE tab DROP COLUMN col5;
ALTER TABLE tab ADD col9 INT;
ALTER TABLE tab ADD col1 INT;
SELECT column_name,
ordinal_position,
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + TABLE_NAME),
COLUMN_NAME, 'ColumnID') AS pos
FROM INFORMATION_SCHEMA.columns
WHERE [TABLE_NAME] like '%tab%'
ORDER BY ordinal_position;
SqlFiddleDemo
Output:
╔══════════════╦═══════════════════╦═════╗
║ column_name ║ ordinal_position ║ pos ║
╠══════════════╬═══════════════════╬═════╣
║ id ║ 1 ║ 1 ║
║ col2 ║ 2 ║ 3 ║
║ col3 ║ 3 ║ 4 ║
║ col4 ║ 4 ║ 5 ║
║ col6 ║ 5 ║ 7 ║
║ col7 ║ 6 ║ 8 ║
║ col8 ║ 7 ║ 9 ║
║ col9 ║ 8 ║ 10 ║
║ col1 ║ 9 ║ 11 ║
╚══════════════╩═══════════════════╩═════╝
Results:
ORIDINAL_POSITION -> no gaps, range 1-9
pos(aka ColumnId) -> gaps, range 1-11, 2 and 6 skipped
Alternatively to check if column has chagned or not you can use UPDATE:
UPDATE ( column )
Returns a Boolean value that indicates whether an INSERT or UPDATE
attempt was made on a specified column of a table or view. UPDATE() is
used anywhere inside the body of a Transact-SQL INSERT or UPDATE
trigger to test whether the trigger should execute certain actions.

SSRS count number of time value exists in data set - countifs equivalent

I am trying to carry out a data quality check in SSRS where by I am counting the number of times a string exists in a dataset to check for duplicate values.
This is one of many checks so I would like to run out a single dataset to cover all the checks. Below outlines what I would like to produce...
╔══════════════╦═══════╗
║ Check Column ║ Count ║
╠══════════════╬═══════╣
║ A1 ║ 1 ║
║ B2 ║ 2 ║
║ C1 ║ 1 ║
║ B2 ║ 2 ║
║ C2 ║ 3 ║
║ C2 ║ 3 ║
║ A2 ║ 1 ║
║ C2 ║ 3 ║
╚══════════════╩═══════╝
However the added complication is that I need to carry this out as a calculated field rather than on a tablix as only the count of the duplicates is needed (5 in the table above).
I have carried out a testbed of this in Excel and the countif function covers this simply enough and gives me the table of data I need but the report should be doing all this work when it is run from a scheduled.
Any ideas on this - happy with a VBA script to use but I can not find anything on the internet on this.
Thanks,
This is the altnerative: =SUM(Iif(Fields!ColumnCheck.Value="SomeString",1,0).

Performance of concatenated column - does order matter?

I need to create a concatenated column based on two other columns in the table. One column is the year (10 distinct values), and one is a person's ID value (~150,000 distinct values). This is being used as a business key by an ETL task that will not accept multiple columns as the key value, so I need to persist this value in my database.
That said, I can choose how to create that value, and I'm wondering if the order (ID + Year or Year + ID) affects performance in any way. If the year goes first, the first four characters will always be one of a limited set of actual years. If the ID goes first, that will change for each user. Is there any difference between the two?
The only usage this column will get is during the ETL load, where it will be used to join data from the source and staging tables to check for differences between the two. The base values will be in the table underneath, and I plan on creating a clustered index on those base values.
Sample Data:
╔══════════════╦══════════════╦═════════╦═════════╗
║ COMPOSITE_1 ║ COMPOSITE_2 ║ AC_YEAR ║ ST_ID ║
╠══════════════╬══════════════╬═════════╬═════════╣
║ 0000001|2005 ║ 2005|0000001 ║ 2005 ║ 0000001 ║
║ 0000001|2006 ║ 2006|0000001 ║ 2006 ║ 0000001 ║
║ 0000001|2009 ║ 2009|0000001 ║ 2009 ║ 0000001 ║
║ 0000001|2010 ║ 2010|0000001 ║ 2010 ║ 0000001 ║
║ 0000001|2012 ║ 2012|0000001 ║ 2012 ║ 0000001 ║
║ 0000001|2013 ║ 2013|0000001 ║ 2013 ║ 0000001 ║
║ 0000002|2005 ║ 2005|0000002 ║ 2005 ║ 0000002 ║
║ 0000002|2006 ║ 2006|0000002 ║ 2006 ║ 0000002 ║
║ 0000002|2007 ║ 2007|0000002 ║ 2007 ║ 0000002 ║
║ 0000002|2008 ║ 2008|0000002 ║ 2008 ║ 0000002 ║
║ 0000002|2009 ║ 2009|0000002 ║ 2009 ║ 0000002 ║
║ 0000002|2010 ║ 2010|0000002 ║ 2010 ║ 0000002 ║
║ 0000002|2012 ║ 2012|0000002 ║ 2012 ║ 0000002 ║
║ 0000002|2013 ║ 2013|0000002 ║ 2013 ║ 0000002 ║
║ 0000002|2014 ║ 2014|0000002 ║ 2014 ║ 0000002 ║
╚══════════════╩══════════════╩═════════╩═════════╝
Question One: would either Composite_1 or Composite_2 give me better performance during the JOIN?
Question Two: would I ever need to index the Composite column, and if so should I do it alone/with others? The SSIS task will be using it for an in-memory JOIN, and I plan to include it as an ORDER BY within my OLE DB Source component.
Question Three: Does the clustered index belong on the Composite column, or the Year and ID columns? EDIT: Or, since I know that Year and ID won't affect the order of Composite, should I just include all three?
Since you're turning these into a string column, the index is going to order them based on the characters in the string. You'll want the field (year or id) with the best distribution and most unique values to be first.
You should index the composite column since it's being used for the join. Whether you want to include other data depends on what data you are pulling back.
If you don't need the clustered index on any other columns, and the table is only being used for BI/data warehouse loading, you may as well put it on the composite column. That way a key lookup won't be required to get any other data you may need.

Sql Server Get Instance Id of New Job

This question is similar, but not quite what I'm looking for: Executing SQL Server Agent Job from a stored procedure and returning job result
I'd like to run a job and return the instance ID for recording in a separate table for reporting. We get daily extracts of files and when we've pre-processed the files we kick off a SQL Agent Job. The same job might get kicked off multiple times in short order, so we need the instance id immediately.
Furthermore, I'm showing the results on a small dash that could really use a "Job Completion Time" column. Right now I've got a separate page that only shows the most recent job status. There's no way to connect the job w/ the completion date.
I suppose that running the job and immediately querying for the highest instance ID of that job would do the trick, but I was really hoping for something a bit more foolproof.
To get the details of Jobs executed you can use the following query aginst dbo.sysjobs and dbo.sysjobhistory tables in MSDB database.
select
j.name as 'JobName',
h.instance_id,
run_date,
run_time,
msdb.dbo.agent_datetime(run_date, run_time) as 'RunDateTime',
run_duration
From msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h
ON j.job_id = h.job_id
where j.enabled = 1 --Only Enabled Jobs
order by run_date, RunDateTime desc
Result Set
╔═══════════════════════════════════════════════════╦═════════════╦══════════╦══════════╦═════════════════════════╦══════════════╗
║ JobName ║ instance_id ║ run_date ║ run_time ║ RunDateTime ║ run_duration ║
╠═══════════════════════════════════════════════════╬═════════════╬══════════╬══════════╬═════════════════════════╬══════════════╣
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 1769 ║ 20130910 ║ 110052 ║ 2013-09-10 11:00:52.000 ║ 3 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 1770 ║ 20130910 ║ 110052 ║ 2013-09-10 11:00:52.000 ║ 3 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 2025 ║ 20130915 ║ 20001 ║ 2013-09-15 02:00:01.000 ║ 4 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 2026 ║ 20130915 ║ 20000 ║ 2013-09-15 02:00:00.000 ║ 5 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 2415 ║ 20130922 ║ 20000 ║ 2013-09-22 02:00:00.000 ║ 17 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 2416 ║ 20130922 ║ 20000 ║ 2013-09-22 02:00:00.000 ║ 17 ║
║ sysDatabase_weekly_Full_Backup_MyServer.Subplan_1 ║ 8804 ║ 20130929 ║ 20000 ║ 2013-09-29 02:00:00.000 ║ 4 ║
╚═══════════════════════════════════════════════════╩═════════════╩══════════╩══════════╩═════════════════════════╩══════════════╝
To see some more cool queries about how to query sql server agent's Job history read this Querying SQL Server Agent Job History Data by Chad Churchwell

Resources