SQL Server : find index of string - sql-server

User table
UserId UserName
55 FirstUser
22 SecondUser
5 ThirdUser
33 FourthUser
I have a username "SecondUser".
I want to match "SecondUser" name with the UserName column, after that I want to get it's index.
How can I find the index of SecondUser in SQL Server?
Any help will be appreciated with points.
Thanks.

Your question makes no sense .... what do you mean by index ??? You can fetch the UserId associated with your user name. But what do you mean by index ? What would the index of SecondUser be in your case??
Update: OK - so you want to have some ordering. But you want your data ordered by what criteria ?? You need some kind of a column - an ID, a DateTime column - SOMETHING that you can use in an ORDER BY clause.
SQL Server doesn't have any implicit ordering per se; if you want to have any ordering (and thus an "index" in that order), you must provide some kind of column(s) to order by.
If you do have an ID column - you could do something like this:
;WITH BaseData AS
(
SELECT
[UserId],
[Index] = ROW_NUMBER() OVER(ORDER BY ID),
UserName
FROM dbo.[User]
)
SELECT *
FROM BaseData
WHERE UserName = 'SecondUser'

Here is the SQLFiddel Demo
Below is the Sample Query :
select *,
row_number() over (order by (select 0)) as 'Index'
from [user]
Note : This answer is applicable only if there is no Clustered Index or Primary Key in [user] table. If there is Primary Key or Clustered Index in your table on any column then while querying Select * from [user] will give the output with Sorted rows on the primary key column or a column on which clustered index is formed.

Related

Snowflake - Deleting a CTE because table has duplicate rows

I have tableA that has duplicate rows, I noticed that some columns are different but essentially I'm told that it doesn't matter and we just want to make sure there is a unique ID in each row.
I tried this in Snowflake but I read we can't use CTEs to delete, insert.. etc. So then how?
WITH cte AS (
SELECT
_LOAD_DATETIME,
_LOAD_FILENAME,
_LOAD_FILE_ROW_NUMBER,
ID,
CONTENT_CATEGORY,
CREATED_TIME,
DESCRIPTION,
FROM_INFO,
LENGTH,
PERMALINK_URL,
POST_VIEWS,
PUBLISHED,
TITLE,
VIEWS,
LOADED_DATE,
ROW_NUMBER() OVER (
PARTITION BY
id,
FROM_INFO,
title
) row_num
FROM
tableA)
DELETE FROM cte
WHERE row_num > 1;
Alternative appraoch could be table recreation:
CREATE OR REPLACE TABLE tableA COPY GRANTS AS
SELECT *
FROM tableA
QUALIFY ROW_NUMBER() OVER (PARTITION BY id, FROM_INFO, title ORDER BY 1) = 1;
we just want to make sure there is a unique ID in each row.
If id has to be unique then it should be partitioned only by id column. Before running the query CTaS it is advisable to check the part without CREATE TABLE part.

Row HASHBYTES in results

I wonder if anyone can help me achieve this. I have a row of 100 columns, 1st being the primary key. I need to retrieve from each row in my query the primary key column and a HASHBYTES of the entire row, so the results would look like:
PK Hash
000123 HASHVALUE1234567890ETC
I can get the entire row with this select statement:
SELECT hashbytes('sha1', (SELECT * From Table Where PK = 000123 FOR XML RAW))
I cannot however work out how to get the PK and hash together in the same results..
Thanks in advance for your help.
Derek.
Select CompanyPK,
(SELECT hashbytes('sha1',
(SELECT * From Company
Where CompanyPK = 'f5dba28b-ae3b-407a-807c-068acde88298' FOR XML RAW)))
as [Hash]
From Company
Where CompanyPK = 'f5dba28b-ae3b-407a-807c-068acde88298'
Sorry to waste your time :)

Missing index (Impact 97) : Create Non Clustered Index

I am trying to optimize my stored procedure. When I look at the query plan, I can see tablescan on tempcompany is showing 97 percent. I am also seeing the following message Missing index (Impact 97) : Create Non Clustered Index on #tempCompany
I have already set non clustered indexes. Could somebody point out what the problem is
if object_id('tempdb..#tempCompany') is not null drop table #tempCompany else
select
fp.companyId,fp.fiscalYear,fp.fiscalQuarter,fi.financialperiodid, fi.periodEndDate,
fc.currencyId,fp.periodtypeid,ROW_NUMBER() OVER (PARTITION BY fp.companyId,
fp.fiscalYear, fp.fiscalQuarter ORDER BY fi.periodEndDate DESC) rowno
into #tempCompany
from
ciqFinPeriod fp
inner join #companyId c on c.val = fp.companyId
join ciqFinInstance fi on fi.financialperiodid = fp.financialperiodid
join ciqFinInstanceToCollection ic on ic.financialInstanceId = fi.financialInstanceId
left join ciqFinCollection fc on fc.financialCollectionId = ic.financialCollectionId
left join ciqFinCollectionData fd on fd.financialCollectionId = fc.financialCollectionId
where
fp.periodTypeId = #periodtypeId
and fi.periodenddate >= #date
--and fp.companyId in (select val from #companyId)
CREATE NONCLUSTERED INDEX id_companyId2 on #tempCompany(companyId,fiscalYear,fiscalQuarter,financialperiodid,periodEndDate,currencyId,periodtypeid,rowno)
if object_id('tempdb..#EstPeriodTbl') is not null drop table #EstPeriodTbl else
select
companyId,fiscalYear,fiscalQuarter,financialPeriodId,periodenddate,currencyId,
periodtypeid,rowno
into #EstPeriodTbl
from #tempCompany a
where a.rowno = 1
order by companyid, periodenddate
CREATE NONCLUSTERED INDEX id_companyId3 on #EstPeriodTbl(companyId,periodenddate,fiscalYear,fiscalQuarter,currencyId,financialPeriodId,rowno)
Execution Plan
You do not need to include everything in the #tempCompany index; just rowno:
CREATE NONCLUSTERED INDEX id_companyId2 on #tempCompany(rowno)
Short answer: The index you provided, does not help SQL Server in the query you are doing. If you create another non-clustered index, and have rowno as the first column in the index, Sql Server will probably be able to use that index.
Long explination:
The reason you have a problem, is because the index you have created isn't useful to SQL Server with this specific query. The order that records are sorted in on an index is determined by the order you specify them when creating an index.
(e.g. Your index orders your records by companyId first, and then orders the records with the same companyId by their fiscalYear, and then by their fiscalQuarter.)
Trying to use the provided index to find an item by just it's rowno value, would be like you trying to find the entries in the phone book based off of someone's phone number. The only way to locate all of the matching records is to search through every record in the book (i.e. a table scan).
In general, you can utalize nonclustered indexs only when the information you use in your where clause matches the first column in your index, (i.e. if you can provide a SARGable predicate for companyId in your where clause, you could probably use this index)
Using the phone book again: If I gave you a last name and a phone number, now you no longer need to do a full table scan on the phone book, you can do an index scan for the last name. Which would be more efficient. And if you were able to give a last name, and first name, and then middle initial and phone number, you could do an even more efficient table scan. But if I only provide you with a last name, middle initial and phone number; now I am back to scaning the index on just the value of last name.
So if you can narrow down your record set to use at least companyId (i.e. use companyID in your where clause) you can use the index you have provided.
Or, and I imagine this is what you will want to do, create an index that sorts by rowno, then companyId and periodendDate.
e.g.
CREATE NONCLUSTERED INDEX idx_temp_rowno ON #tempCompany(rowno, companyId, periodenddate)

SQL - Assign Unique ID for DISTINCT records

I need to create at temp table that has two columns: language_id (number) and language (text). I have a customer table that contains my language column. I need to populate my temp table with distinct records from my language column and I need to be able to assign a language_id for each distinct language record.
I am using 'SELECT DISTINCT Language from CustomerData' to get distinct records, but I am not certain how to assign a language_id for each distinct record.
My desired output is below
Language ID Language
1 English
2 French
3 Spanish
Any help would be much appreciated. Thank you
it's Simple group by "Language" on "CustomerData" data and ROW_NUMBER() to assign DISTINCT row number:
select ROW_NUMBER() OVER( ORDER BY Language asc) as ID, Language
from CustomerData
group by Language
If you want it in a table, set Language_ID as IDENTITY. If you want the result of a query, try this:
SELECT
t.Language
, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Language_ID
FROM
(SELECT DISTINCT Language FROM CUSTOMER_DATA) t
You can use the below query to achieve the same
INSERT INTO temp_table
SELECT DISTINCT DENSE_RANK() OVER(ORDER BY [Language] ) Language_ID,
,[Language]
FROM CustomerData
ORDER BY Language_ID
Otherwise as suggested in comments you can use Language_ID as IDENTITY column and use the simple query below
INSERT INTO temp_table(Language)
SELECT DISTINCT [Language]
FROM CustomerData
ORDER BY CustomerData
SELECT
[Language ID] = ROW_NUMBER() OVER(ORDER BY [Language])
,[Language] = [Language]
FROM
[CustomerData]
GROUP BY
[Language];
You must be having master / lookup table to gt this ID from that table.
Incase you have it, i would recommoned to use that table and JOIN it in your query to populate language id.
In case you don't have a master table for Language,
You can use Row_number() to get distinct rows with LanguageID
select ROW_NUMBER() OVER (order by Language ASC) , Language from
(
SELECT DISTINCT Language from CustomerData
)
Create the temporary table:
CREATE TABLE ##TempLanguage (
[LanguageId] [int] IDENTITY(1,1) NOT NULL, -- note use of IDENTITY field to assign LanguageId value
[Language] [nvarchar](100) NOT NULL,
) ON [PRIMARY]
Load the temporary table:
INSERT ##TempLanguage (
[Language]
)
SELECT DISTINCT [Language] FROM [CustomerData] ORDER BY [Language];
Display the temporary table's contents:
SELECT [LanguageId], [Language] FROM ##TempLanguage;
Remove the temporary table:
DROP TABLE ##TempLanguage
Note that beginnning the name of a temporary table with a double hash-tag, such as ##TempLanguage, creates a temporary table that persists between database connections and can be shared between database connections. Beginning the name of a temporary table with a single hash-tag, such as #TempLanguage creates a temporary table that persists for the length of the current connection, and is visible only to the current database connection.
In addition to all the existing answers, you can add an identity column to your table afterwards.
ALTER TABLE <table-name> ADD
LanguageId int IDENTITY(1, 1) NOT NULL
This will assign an incremental id to all rows currently in the table when the column is added.

Database Index when SQL statement includes "IN" clause

I have SQL statement which takes really a lot of time to execute and I really had to improve it somehow.
select * from table where ID=1 and GROUP in
(select group from groupteam where
department= 'marketing' )
My question is if I should create index on columns ID and GROUP would it help?
Or if not should I create index on second table on column DEPARTMENT?
Or I should create two indexes for both tables?
First table has 249003.
Second table has in total 900 rows while query in that table returns only 2 rows.
That is why I am surprised that response is so slow.
Thank you
You can also use EXISTS, depending on your database like so:
select * from table t
where id = 1
and exists (
select 1 from groupteam
where department = 'marketing'
and group = t.group
)
Create a composite index on individual indexes on groupteam's department and group
Create a composite index or individual indexes on table's id and group
Do an explain/analyze depending on your database to review how indexes are being used by your database engine.
Try a join instead:
select * from table t
JOIN groupteam gt
ON d.group = gt.group
where ID=1 AND gt.department= 'marketing'
Index on table group and id column and table groupteam group column would help too.

Resources