SQL Order By not working properly - sql

I have a table like this
CREATE TABLE [dbo].[tbl_LandRigs](
[ID] [int] IDENTITY(700000,1) NOT NULL,
[Company] [nvarchar](500) NULL,
[Rig] [nvarchar](500) NULL,
[RigType] [nvarchar](200) NULL,
[DrawWorks] [nvarchar](500) NULL,
[TopDrive] [nvarchar](200) NULL,
[RotaryTable] [nvarchar](500) NULL,
[MudPump] [nvarchar](500) NULL,
[MaxDD] [nvarchar](50) NULL,
[Operator] [nvarchar](500) NULL,
[Country] [nvarchar](200) NULL,
[Location] [nvarchar](500) NULL,
[OPStatus] [nvarchar](200) NULL,
[CreatedDate] [datetime] NULL,
[CreatedByID] [int] NULL,
[CreatedByName] [nvarchar](50) NULL,
CONSTRAINT [PK_tbl_LandRigs] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
And I am trying to get data from MaxDD column in Descending order
SELECT distinct "MaxDD" FROM [tbl_LandRigs] ORDER BY "MaxDD" Desc
But this returns data in following order
According to my calculation 4000 must be the first value followed by others.But this results astonished me.Can any one help me out in this?

You are storing them as text(nvarchar), that's why you get lexographical order. That means every character is compared with each other from left to right. Hence 4000 is "higher" than 30000 (the last zero doesn't matter since the first 4 is already higher than the 3).
So the correct way is to store it as a numeric value. However, that seems to be impossible since you also use values like 16.000 with 4.1/2"DP. Then i would add another column, one for the numeric value you want to order by and the other for the textual representation.

As MaxDD is a varchar, not a number it is sorted in lexicographical order (i.e. ordered by the first character, then second, ...), not numerical. You should convert it to a numerical value

This behaviour is due to the nvarchar type.
Try this:
SELECT distinct "MaxDD" FROM [tbl_LandRigs] ORDER BY CAST ("MaxDD" as Int)

Related

Optimize performance on SQL table - indexing

I have a table in my DB which contains 5 million records:
CREATE TABLE [dbo].[PurchaseFact](
[Branch] [int] NOT NULL,
[ProdAnal] [varchar](30) NULL,
[Account] [varchar](12) NULL,
[Partno] [varchar](24) NULL,
[DteGRN] [date] NULL,
[DteAct] [date] NULL,
[DteExpect] [date] NULL,
[OrderNo] [bigint] NULL,
[GRNNO] [varchar](75) NULL,
[SuppAdv] [varchar](75) NULL,
[Supplier] [varchar](12) NULL,
[OrdType] [varchar](4) NULL,
[UnitStock] [varchar](4) NULL,
[OrderQty] [float] NULL,
[RecdQty] [float] NULL,
[Batch] [varchar](100) NULL,
[CostPr] [float] NULL,
[Reason] [varchar](2) NULL,
[TotalCost] [float] NULL,
[Magic] [bigint] IDENTITY(1,1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Magic] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
As you can see from the above - a CLUSTERED INDEX is being used on the MAGIC column which is a UNIQUE column.
Data retrieval time for the following SELECT statement is well over 8mins which causes reporting issues:
SELECT Branch,
Supplier,
ProdAnal,
DteGRN AS Date,
PartNo AS Partno,
OrderNo,
OrderQty,
TotalCost,
CostPr
FROM dbo.PurchaseFact src
WHERE YEAR(DteGRN) = 2016
Excluding the WHERE clause also doesn't make the query run any faster.
I have tried, together with the CLUSTERED index to include a UNIQUE index in the hopes that it would run faster but to no avail :
CREATE UNIQUE INDEX Unique_Index ON dbo.PurchaseFact ([Branch], [Supplier], [Magic])
INCLUDE ([ProdAnal], [Account], [Partno], [DteAct], [DteExpect], [OrderNo], [GRNNO],
[SuppAdv], [OrdType], [UnitStock])
Is there any way I can optimize performance time on this table or should I resort to archiving old data?
Any advice would be greatly appreciated.
This is your where clause:
WHERE YEAR(DteGRN) = 2016
If the table has 5 million rows, then this is going to return a lot of data, assuming any reasonable distribution of dates. The volume of data is probably responsible for the length of time for the query.
One thing you can do is to rephrase the WHERE and then put an index on the appropriate column:
WHERE DteGRN >= '2016-01-01' and DteGRN < '2017-01-01'
This can then take advantage of an index on PurchaseFact(DteGRN). However, given the likely number of rows being returned, the index probably will not help very much.
The bigger question is why your reporting application is bringing back all the rows from 2016, rather than summarizing them inside the database. I suspect you have an architecture issue with the reporting application.
Sorry, can't add comments.
To help improve performance further (if you can live with the UPDATE overhead), create a COVERING INDEX that INCLUDES only the columns in the SELECT part of the query.

1 billion rows DW to DM

I have a design/performance question.
I have this next table.
CREATE TABLE [dbo].[DW_Visits_2016](
[VisitId] [int] NOT NULL,
[UserId] [int] NOT NULL,
[VisitReferrer] [varchar](512) NULL,
[VisitFirstRequest] [varchar](255) NOT NULL,
[VisitAppName] [varchar](255) NULL,
[VisitCountry] [varchar](50) NULL,
[VisitDate] [smalldatetime] NOT NULL,
[VisitMins] [int] NOT NULL,
[VisitHits] [int] NOT NULL,
[EntryTag] [varchar](100) NOT NULL,
[VisitCount] [int] NOT NULL,
[VisitInitialDate] [datetime] NOT NULL,
[AggregateType] [varchar](50) NULL,
[MemberId] [int] NULL,
[ServerName] [varchar](50) NULL,
[BrowserUserAgent] [varchar](255) NULL,
[LastModifiedDate] [smalldatetime] NULL,
[Guid] [uniqueidentifier] NULL,
[SessionId] [varchar](100) NULL,
[IPAddress] [varchar](40) NULL,
CONSTRAINT [PK_Visits] PRIMARY KEY NONCLUSTERED
(
[VisitId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Visits] WITH CHECK ADD CONSTRAINT [CK_Visits_VisitDate] CHECK (([VisitDate]>='2016-01-01' AND [VisitDate]<'2017-01-01'))
GO
ALTER TABLE [dbo].[Visits] CHECK CONSTRAINT [CK_Visits_VisitDate]
And this same table for 2015 ... 2010.
Every table has around 150 million rows. So, combined we are talking about 1,050 million rows.
I received a requirement where BI people wants to have this combined on a single view (Something crazy like select * from all_visits).
Luckily they gave me some ‘where’ clauses, and some columns they don’t need, so the final result would be 6 columns and 20% of the rows (210 million rows), but nonetheless, a ‘view’ is just a stored query. Even though the box has 60GB of ram, it’s shared with many other databases.
Options I see:
Instead of a view… Creating the views as tables and move them to a dedicated box.
Create one view per year?
Switch all of this to mongodb or something like vertica?!
Any of the previous options combined with column stored indexes?

Conversion failed when converting the varchar value 'a' to data type int

Something must be wrong with my ADDRESS table's definition. When inserting or selecting rows, it is treating the LINE1 column as int, but clearly I have declared it as varchar(128).
This command works fine:
insert into address(PERSON_ID, LINE1, TYPE_ID)
values (234, 'a', 1)
But in SQL Server Management Studio, when I do "Edit top 200 rows" and try to insert the same values, I get an error message.
After having inserted via SQL query, selecting rows from the table gives same error message.
Error message I get when inserting via SSMS Edit rows feature, or C#, and when selecting:
Conversion failed when converting the varchar value 'a' to data type int.
ADDRESS table:
CREATE TABLE [dbo].[ADDRESS]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[PERSON_ID] [int] NOT NULL,
[LINE1] [varchar](128) NOT NULL,
[LINE2] [varchar](128) NULL,
[CITY] [varchar](256) NULL,
[COUNTY_ID] [int] NULL,
[STATE] [int] NULL,
[POSTAL_CODE] [varchar](16) NULL,
[COUNTRY_ID] [int] NULL,
[TYPE_ID] [int] NOT NULL,
[DESCRIPTION] AS ([dbo].[GET_ADDRESS_STRING]([ID])),
CONSTRAINT [PK_ADDRESS]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

SQL UniqueIdentifier

I have a table called UserCredentials and it has a uniqueidentifier column [UserCredentialId]. When I try to create a new user, I get 00000000-0000-0000-0000-000000000000 in my first try, then when I try adding another user, it says PK cannot be duplicated. At first I had a hard time guessing what does it mean but, I think its because of my uniqueidentifier is not generating random id.
What to do?
EDIT
Here is my SQL table structure:
CREATE TABLE [dbo].[UserCredential](
[UserCredentialId] [uniqueidentifier] NOT NULL,
[UserRoleId] [int] NOT NULL,
[Username] [varchar](25) NOT NULL,
[Password] [varchar](50) NOT NULL,
[PasswordSalt] [varchar](max) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[PayorCode] [varchar](20) NOT NULL,
[ProviderCode] [varchar](50) NULL,
[CorporationCode] [varchar](50) NULL,
[Department] [varchar](50) NULL,
[Status] [varchar](1) NOT NULL,
[DateCreated] [datetime] NOT NULL,
[DateActivated] [datetime] NULL,
[Deactivated] [datetime] NULL,
[DateUpdated] [datetime] NULL,
[CreatedBy] [varchar](50) NOT NULL,
[UpdatedBy] [varchar](50) NOT NULL,
[EmailAddress] [varchar](50) NULL,
[ContactNumber] [int] NULL,
[Picture] [varbinary](max) NULL,
CONSTRAINT [PK_UserCredential_1] PRIMARY KEY CLUSTERED
(
[UserCredentialId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I already set it to (newid()) but still not working.
Set the Id of your user instance to Guid.NewGuid();
user.Id = Guid.NewGuid();
Change your table definition to
[UserCredentialId] UNIQUEIDENTIFIER DEFAULT (NEWSEQUENTIALID()) NOT NULL
Check why prefer NEWSEQUENTIALID than newid at http://technet.microsoft.com/en-us/library/ms189786.aspx.
When a GUID column is used as a row identifier, using NEWSEQUENTIALID can be faster than using the NEWID function. This is because the NEWID function causes random activity and uses fewer cached data pages. Using NEWSEQUENTIALID also helps to completely fill the data and index pages.
You can have all values in the table default to a new value during insert, much like an IDENTITY.
Run this to set the default of all inserts to use newid().
ALTER TABLE [dbo].[UserCredential] ADD CONSTRAINT [DF_UserCredential_UserCredentialID] DEFAULT (newid()) FOR [UserCredentialId]
GO

converting computed column to a specific datatype

I am currently trying to execute some SQL Query in SQLSERVER 2008 R2 form my Java GUI. I am working on currency management system.
I have to store Long data type values as the figure of currency may exceed than 10 digits but the computed column dose not show any data type option in the design view of the table. I really Need help regarding this as my value exceeds than 10 digits and I need to select total value from my database. I have tried to execute the code but its showing some sort of overflow error please help
The following is my script file of the table from database name CNV
USE [CNV]
CREATE TABLE [dbo].[soil_det](
[ID] [int] IDENTITY(1,1) NOT NULL,
[rm_id] [bigint] NULL,
[box_no] [int] NULL,
[weight] [decimal](18, 2) NULL,
[note_state] [varchar](10) NULL,
[dm_state] [varchar](10) NULL,
[1] [int] NULL,
[2] [int] NULL,
[5] [int] NULL,
[10] [int] NULL,
[20] [int] NULL,
[50] [int] NULL,
[100] [int] NULL,
[500] [int] NULL,
[1000] [int] NULL,
[tp] AS (((((((([1]+[2])+[5])+[10])+[20])+[50])+[100])+[500])+[1000]),
[tv] AS (((((((([1]*(1)+[2]*(2))+[5]*(5))+[10]*(10))+[20]*(20))+[50]*(50))+[100]*(100))+[500]*(500))+[1000]*(1000)) PERSISTED,
[tp_ex1] AS ((((((([2]+[5])+[10])+[20])+[50])+[100])+[500])+[1000]),
[tv_ex1] AS ((((((([2]*(2)+[5]*(5))+[10]*(10))+[20]*(20))+[50]*(50))+[100]*(100))+[500]*(500))+[1000]*(1000)),
[val_1] AS ([1]*(1)),
CONSTRAINT [PK_mut_det] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
here is solution for this , you can do something as given in image
Check the full article over here : SQL SERVER – Puzzle – Solution – Computed Columns Datatype Explanation