Quick question - I want to create another column in SQL Server such as:
Original Table
Type Amount LocNum
Chocolate 15 WC-10202-01
Banana 10 WC-35209-22
Vanilla 5 WC-15815-15
Ideal Table
Type Amount LocNum LocNum2
Chocolate 15 WC-10202-01 WC-10202
Banana 10 WC-35209-22 WC-35209
Vanilla 5 WC-15815-15 WC-15815
If you really need to, you can create a computed column.
ALTER TABLE yourTable ADD LocNum2 AS ( <your calculation here> );
However, unless you need to index on this calculation for some reason, I'd suggest just adding it as a part of your select output.
You can use replace and charindex to do this as below:
select [Type], [Amount], LocNum, LocNum2 = replace(LocNum,right(LocNum, charindex('-',LocNum,charindex('-',LocNum,1))),'')
from yourtable
As simple as that:
ALTER TABLE table_name
ADD column_name column-definition;
Related
I am trying to set up a database that has the following columns, "number", "full names", "card no", "status". In the last column status there are many types of status, which I would like to have them converted to 0 or 1 to another column within the table, depending on the statuses. The database then, is to be pulled to another application and will use the binary column to give access to a facility.
I have not tried any code on this, still learning.
SELECT TOP 1000 [MemberNo]
,[FirstName]
,[LastName]
,[CardNo]
,[Status]
FROM [GateAccess].[dbo].[GateProxy]
Not sure why ask a question when you havent tried anything...
First you are trying to create a table with following columns not a database.
Here is a link of how to create a table http://www.mysqltutorial.org/mysql-create-table/
Second you dont really need to to convert char to numeric I would personally use CASE
here is a link on case https://www.techonthenet.com/mysql/functions/case.php
Regarding to your 'application and will use the binary column to give access to a facility' it depends on what application is pulling the data.
This may help ...
DECLARE #sampletext VARCHAR(100) = '123456';
SELECT TRY_CONVERT(INT, #sampletext); -- 123456
SELECT TRY_CAST(#sampletext AS INT); -- 123456
SELECT TOP 1000 [MemberNo]
,[FirstName]
,[LastName]
,[CardNo]
,[Status]
-- Try like this for new derived column
,CASE WHEN [Status] = 'yourValue'THEN 1
WHEN [Status] = 'yourOtherValue' THEN 0
END
FROM [GateAccess].[dbo].[GateProxy]
Hi I have procedure which have parameter(#identFormat)
Example
"GUID"
"LotID|FeatureID"
And now I have Select query which should split this and use as columns.
Moreover result should be back combined.
Example:
Table:
Id LotID FeatureID
2 1 4
3 4 5
4 2 1
and if my #identFormat = "LotID|FeatureID" then it should return
Table:
1|4
4|5
2|1
Actually I have ncharchar #columns 'LotId + "|" + FeatureId'
Is it possible to use this like this:
Select #columns from Table ?
or using dynamic sql
EDIT:
Unfortunately combination of columns can be different. My purpose is send column names to procedure and select this columns from specific table. This is procedure to save data , but if something went wrong I must save this unique combination of columns in second table.
Unfortunatelly, it is not possible. You need to select separately and format the output
I have a view that may contain more than one row, looking like this:
[rate] | [vendorID]
8374 1234
6523 4321
5234 9374
In a SPROC, I need to set a param equal to the value of the first column from the first row of the view. something like this:
DECLARE #rate int;
SET #rate = (select top 1 rate from vendor_view where vendorID = 123)
SELECT #rate
But this ALWAYS returns the LAST row of the view.
In fact, if I simply run the subselect by itself, I only get the last row.
With 3 rows in the view, TOP 2 returns the FIRST and THIRD rows in order. With 4 rows, it's returning the top 3 in order. Yet still top 1 is returning the last.
DERP?!?
This works..
DECLARE #rate int;
CREATE TABLE #temp (vRate int)
INSERT INTO #temp (vRate) (select rate from vendor_view where vendorID = 123)
SET #rate = (select top 1 vRate from #temp)
SELECT #rate
DROP TABLE #temp
.. but can someone tell me why the first behaves so fudgely and how to do what I want? As explained in the comments, there is no meaningful column by which I can do an order by. Can I force the order in which rows are inserted to be the order in which they are returned?
[EDIT] I've also noticed that: select top 1 rate from ([view definition select]) also returns the correct values time and again.[/EDIT]
That is by design.
If you don't specify how the query should be sorted, the database is free to return the records in any order that is convenient. There is no natural order for a table that is used as default sort order.
What the order will actually be depends on how the query is planned, so you can't even rely on the same query giving a consistent result over time, as the database will gather statistics about the data and may change how the query is planned based on that.
To get the record that you expect, you simply have to specify how you want them sorted, for example:
select top 1 rate
from vendor_view
where vendorID = 123
order by rate
I ran into this problem on a query that had worked for years. We upgraded SQL Server and all of a sudden, an unordered select top 1 was not returning the final record in a table. We simply added an order by to the select.
My understanding is that SQL Server normally will generally provide you the results based on the clustered index if no order by is provided OR off of whatever index is picked by the engine. But, this is not a guarantee of a certain order.
If you don't have something to order off of, you need to add it. Either add a date inserted column and default it to GETDATE() or add an identity column. It won't help you historically, but it addresses the issue going forward.
While it doesn't necessarily make sense that the results of the query should be consistent, in this particular instance they are so we decided to leave it 'as is'. Ultimately it would be best to add a column, but this was not an option. The application this belongs to is slated to be discontinued sometime soon and the database server will not be upgraded from SQL 2005. I don't necessarily like this outcome, but it is what it is: until it breaks it shall not be fixed. :-x
How can I show the number of rows in a table in a way that when a new record is added the number representing the row goes higher and when a record is deleted the number gets updated accordingly?
To be more clear,suppose I have a simple table like this :
ID int (primary key) Name varchar(5)
The ID is set to get incremented by itself (using identity specification) so it can't represent the number of row(record) since if I have for example 3 records as:
ID NAME
1 Alex
2 Scott
3 Sara
and I delete Alex and Scott and add a new record it will be:
3 Sara
4 Mina
So basically I'm looking for a sql-side solution for doing this so that I don't change anything else in the source code in multiple places.
I tried to write something to get the job done but it failes. Here it is :
SELECT COUNT(*) AS [row number],Name
FROM dbo.Test
GROUP BY ID, Name
HAVING (ID = ID)
This shows as:
row number Name
1 Alex
1 Scott
1 Sara
while I want it to get shown as:
row number Name
1 Alex
2 Scott
3 Sara
If you just want the number against the rows while selecting the data and not in the database then you can use this
select row_number() over(order by id) from dbo.Test
This will give the row number n for nth row.
Try
SELECT id, name, ROW_NUMBER() OVER (ORDER BY id) AS RowNumber
FROM MyTable
What you want is called an auto increment.
For SQL-Server this is achieved by adding the IDENTITY(1,1) attribute to the table definition.
Other RDBMS use a different syntax. Firebird for example has generators, which do the counting. In a BEFORE-INSERT trigger you would assign the ID-field to the current value of the generator (which will be increased automatically).
I had this exact problem a while ago, but I was using SQL Server 2000, so although row number() is the best solution, in SQL Server 2000, this isn't available. A workaround for this is to create a temporary table, insert all the values with auto increment, and replace the current table with the new table in T-SQL.
I have a table defined like this:
Column: Version Message
Type: varchar(20) varchar(100)
----------------------------------
Row 1: 2.2.6 Message 1
Row 2: 2.2.7 Message 2
Row 3: 2.2.12 Message 3
Row 4: 2.3.9 Message 4
Row 5: 2.3.15 Message 5
I want to write a T-Sql query that will get message for the MAX version number, where the "Version" column represents a software version number. I.e., 2.2.12 is greater than 2.2.7, and 2.3.15 is greater than 2.3.9, etc. Unfortunately, I can't think of an easy way to do that without using CHARINDEX or some complicated other split-like logic. Running this query:
SELECT MAX(Version) FROM my_table
will yield the erroneous result:
2.3.9
When it should really be 2.3.15. Any bright ideas that don't get too complex?
One solution would be to use a table-valued split function to split the versions into rows and then combine them back into columns so that you can do something like:
Select TOP 1 Major, Minor, Build
From ( ...derived crosstab query )
Order By Major Desc, Minor Desc, Build Desc
Actually, another way is to use the PARSENAME function which was meant to split object names:
Select TOP 1 Version
From Table
Order By Cast(Parsename( Z.Version , 3 ) As Int) Desc
, Cast(Parsename( Z.Version , 2 ) As Int) Desc
, Cast(Parsename( Z.Version , 1 ) As Int) Desc
Does it have to be efficient on a large table? I suggest you create an indexed persisted computed column that transform the version into a format that ranks correctly, and use the computed column in your queries. Otherwise you'll always scan end to end.
If the table is small, it doesn't matter. Then you can use a just-in-time ranking, using a split function, or (ab)using the parsename as Thomas suggested.