I have single row should convert into columns - sql

Please tell how to display them like
|NumberOfQuotesGenerated | 11 |
TotalAmountOfQuotes | 78100 |
NumberOfInvoiceGenerated | 9 |
TotalAmountOfInvoice | 8222
Thank you in advance

you can try Unpivot syntax like below
-- create table t(NumberOfQuotesGenerated int,TotalAmountOfQuotes int,NumberOfInvoiceGenerated int, TotalAmountOfInvoice int)
-- insert into t values (11, 78100, 9, 8222)
select * from
(select * from t) s
unpivot
(
data for
colname in
([NumberOfQuotesGenerated],[TotalAmountOfQuotes],[NumberOfInvoiceGenerated],[TotalAmountOfInvoice])
)up
Live SQL demo

Related

SQL Server : drop zeros from col1 and concat with col2 into new View

I need to reconcile article1 (top) and article2 tables into a View displaying differences. But before that I need to drop all zeros from column 'type'. Create new ID column equals to filenumber + type so the resulting column should be use as index. All columns share same data type
Columns needed:
ID
C0016
C0029
C00311
You can utilize below script in SQL Server to get the format you want:
Reference SO post on removing padding 0
SELECT CONCAT(filenumber,type) AS filenumber, type, cost
FROM
(
SELECT
filenumber,
SUBSTRING(type, PATINDEX('%[^0]%',type),
LEN(type)- PATINDEX('%[^0]%',type)+ 1) AS type, cost
FROM
(
VALUES
('C001','00006',40),
('C002','00009',80),
('C003','00011',120)
) as t(filenumber,type, cost)
) AS t
Resultset
+------------+------+------+
| filenumber | type | cost |
+------------+------+------+
| C0016 | 6 | 40 |
| C0029 | 9 | 80 |
| C00311 | 11 | 120 |
+------------+------+------+
You can use try_convert() :
alter table table_name
add id as concat(filenumber, try_convert(int, type)) persisted -- physical storage
If you want a view :
create view veiw_name
as
select t.*, concat(filenumber, try_convert(int, type)) as id
from table t;
try_convert() will return null whereas conversation fails.

How to ORDER BY Alphanumeric values in SQL specific columns

create table Employee(id int, Registration_no varchar(50),Name varchar(50))
insert into #Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into #Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into #Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into #Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into #Employee values(5,'DLW/TTC/19/8','RITESH')
insert into #Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into #Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into #Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into #Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into #Employee values(10,'DLW/TTC/19/10','ROSHNI')
select * from Employee
Hello I have the table given above.
Actually am facing problem while am trying to order this table's column (Registration_no)
So kindly help me to ORDER it according to its (Registration_no) column
Its not matter that how the other columns are arranged. I just want my Registration_no column to be arranged in the specific order like this
Registration_no
DLW/TTC/19/1
DLW/TTC/19/2
DLW/TTC/19/3
DLW/TTC/19/4
DLW/TTC/19/5
DLW/TTC/19/6
DLW/TTC/19/7
DLW/TTC/19/8
DLW/TTC/19/9
DLW/TTC/19/10
This will sort by the digits to the right of the last / in the Registration_No string. I'm only including the SortColumn in the result set so you can see the values. You can omit it from your query.
SELECT
e.*,
CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER) AS SortColumn
FROM #Employee AS e
ORDER BY
CAST(RIGHT(e.Registration_no,CHARINDEX('/',REVERSE(e.Registration_no))-1) AS INTEGER)
Results:
+----+-----------------+---------+------------+
| id | Registration_no | Name | SortColumn |
+----+-----------------+---------+------------+
| 3 | DLW/TTC/19/1 | RUPAK | 1 |
| 2 | DLW/TTC/19/2 | RAJEEV | 2 |
| 1 | DLW/TTC/19/3 | RAMESH | 3 |
| 4 | DLW/TTC/19/4 | RAMLAAL | 4 |
| 9 | DLW/TTC/19/5 | SHRISTI | 5 |
| 6 | DLW/TTC/19/6 | HRITIK | 6 |
| 8 | DLW/TTC/19/7 | RUPALI | 7 |
| 5 | DLW/TTC/19/8 | RITESH | 8 |
| 7 | DLW/TTC/19/9 | ROSHAN | 9 |
| 10 | DLW/TTC/19/10 | ROSHNI | 10 |
+----+-----------------+---------+------------+
The SortColumn functions first REVERSE the string, then use CHARINDEX to find the position from the end of the string of the last occurrence of /, then take that number -1 from the right side of the original column (-1 to exclude the / itself).
You can use reverse function together with charindex function
SELECT e.*, cast( reverse(substring(reverse(Registration_no),1,
charindex('/',reverse(Registration_no),1) -1 ) ) as int ) as nr
FROM employee e
ORDER BY nr;
Demo
The main principle is extracting the pieces and converting them to a numerical value, such as integer, in the tail part of the string values. It's easier to operate from the beginning with substring function to this extraction provided reverse function is used to make read the string reversely. And in this case we need to determine the position of the first delimiter(/) by contribution of charindex function. All those functions exist since the version 2008.
If the pattern at the end of Registration_no is always like /X or /XX then:
select * from Employee
order by
case left(right(Registration_no, 2), 1)
when '/' then
left(Registration_no, len(Registration_no) - 1) + '0' + right(Registration_no, 1)
else Registration_no
end
See the demo.
Although I dont like the way the number is extracted, this is how it can be done
select cast(substring(registration_no, charindex('/', registration_no, len(registration_no) -3) + 1, 3) as int),
* from Employee
order by 1
I would suggest you order it on the frontend using regex assuming that you are wanting to order it for display purpose.
How about this.
select *
from Employee
order by LEFT(Registration_no,PATINDEX('%[0-9]%',Registration_no)-1)-- alpha sort
, CONVERT(INT,REPLACE(SUBSTRING(Registration_no,PATINDEX('%[0-9]%',Registration_no),PATINDEX('%[0-9]%',Registration_no)),'/', '')) -- number sort
The first thing you'll notice as you try to order by the Registration_no is that it will be ordered alphabetically due to the nature of the string contents of the column of type varchar. So the correct way to do it is to convert the last two parts of the reg no into numbers and use them in an order by clause. (in this case we can use only the last part since the 2nd last is always 19)
Doing a bit of search I found this function 'Parsename' which has a usage in replication scenarios as it splits the SQL object schema name into its forming parts, so we can use it here (as long as the reg no parts doesn't exceed 4 parts "the SQL objects maximum parts")
So this will work in that case in SQL Server (T-SQL):
SELECT *
FROM Employee
order by cast(Parsename(replace(Registration_no,'/','.'),1) as int)
More info here
Thanks
Try this query.
create table #Employee(id int, Registration_no varchar(50),Name varchar(50))
insert into #Employee values(1,'DLW/TTC/19/3','RAMESH')
insert into #Employee values(2,'DLW/TTC/19/2','RAJEEV')
insert into #Employee values(3,'DLW/TTC/19/1','RUPAK')
insert into #Employee values(4,'DLW/TTC/19/4','RAMLAAL')
insert into #Employee values(5,'DLW/TTC/19/8','RITESH')
insert into #Employee values(6,'DLW/TTC/19/6','HRITIK')
insert into #Employee values(7,'DLW/TTC/19/9','ROSHAN')
insert into #Employee values(8,'DLW/TTC/19/7','RUPALI')
insert into #Employee values(9,'DLW/TTC/19/5','SHRISTI')
insert into #Employee values(10,'DLW/TTC/19/10','ROSHNI')
select * from #Employee
order by Registration_no
id Registration_no Name
----------- -------------------------------------------------- --------------------------------------------------
3 DLW/TTC/19/1 RUPAK
10 DLW/TTC/19/10 ROSHNI
2 DLW/TTC/19/2 RAJEEV
1 DLW/TTC/19/3 RAMESH
4 DLW/TTC/19/4 RAMLAAL
9 DLW/TTC/19/5 SHRISTI
6 DLW/TTC/19/6 HRITIK
8 DLW/TTC/19/7 RUPALI
5 DLW/TTC/19/8 RITESH
7 DLW/TTC/19/9 ROSHAN

Find specific values and trancate

How to find group values?
Example I have following SKU's:
SkuId Description
VN0A46ZERWV113000M CLASSIC
VN0A46ZERWV112000M CLASSIC
VN0A46ZERWV111500M CLASSIC
VN0A3WCVAZ31XXL Modern
VN0A3WCVAZ310XL Modern
VN0A3WCVAZ3100S Modern
VN0A3WCVAZ3100M Modern
VN0A3TE3RCO113000M Not Classic
VN0A3TE3RCO112000M Not Classic
VN0A3TE3RCO111500M Not Classic
How to describe...:) So, I need find all Sku's with the same description, find the same part in SKU, and add new row after every group. In general, the same part is first 12 characters.
Example in Result:
SkuId Description
VN0A46ZERWV113000M CLASSIC
VN0A46ZERWV112000M CLASSIC
VN0A46ZERWV111500M CLASSIC
VN0A46ZERWV1 NEW
VN0A3WCVAZ31XXL Modern
VN0A3WCVAZ310XL Modern
VN0A3WCVAZ3100S Modern
VN0A3WCVAZ3100M Modern
VN0A3WCVAZ31 NEW
VN0A3TE3RCO113000M Not Classic
VN0A3TE3RCO112000M Not Classic
VN0A3TE3RCO111500M Not Classic
VN0A3TE3RCO1 NEW
If I understand correctly you can try to use UNION ALL and substring function to make it.
use substring to get the first 12 characters from SkuId column in subquery then distinct remove duplicate first 12 characters SkuId then UNION ALL two result set.
CREATE TABLE T(
SkuId VARCHAR(100),
Description VARCHAR(100)
);
INSERT INTO T VALUES ('VN0A46ZERWV113000M' ,'CLASSIC');
INSERT INTO T VALUES ('VN0A46ZERWV112000M' ,'CLASSIC');
INSERT INTO T VALUES ('VN0A46ZERWV111500M' ,'CLASSIC');
INSERT INTO T VALUES ('VN0A3WCVAZ31XXL' ,'Modern');
INSERT INTO T VALUES ('VN0A3WCVAZ310XL' ,'Modern');
INSERT INTO T VALUES ('VN0A3WCVAZ3100S' ,'Modern');
INSERT INTO T VALUES ('VN0A3WCVAZ3100M' ,'Modern');
INSERT INTO T VALUES ('VN0A3TE3RCO113000M' ,'Not Classic');
INSERT INTO T VALUES ('VN0A3TE3RCO112000M' ,'Not Classic');
INSERT INTO T VALUES ('VN0A3TE3RCO111500M' ,'Not Classic');
Query 1:
SELECT * FROM (
select SkuId,Description
from T
UNION ALL
SELECT distinct substring(SkuId,1,12) ,'New'
FROM T
) t1
order by SkuId desc
Results:
| SkuId | Description |
|--------------------|-------------|
| VN0A46ZERWV113000M | CLASSIC |
| VN0A46ZERWV112000M | CLASSIC |
| VN0A46ZERWV111500M | CLASSIC |
| VN0A46ZERWV1 | New |
| VN0A3WCVAZ31XXL | Modern |
| VN0A3WCVAZ310XL | Modern |
| VN0A3WCVAZ3100S | Modern |
| VN0A3WCVAZ3100M | Modern |
| VN0A3WCVAZ31 | New |
| VN0A3TE3RCO113000M | Not Classic |
| VN0A3TE3RCO112000M | Not Classic |
| VN0A3TE3RCO111500M | Not Classic |
| VN0A3TE3RCO1 | New |
I think the additional rows you want are:
select skuid, 'NEW'
from (select distinct left(skuid, 12) as skuid, description
from skus
) t;
For your data and probably for your problem, this will probably do:
select distinct left(skuid, 12) as skuid, 'New'
from skus;
If you specifically want to exclude "names" that have different descriptions:
select left(skuid, 12) as skuid, 'New'
from skus
group by left(skuid, 12)
having min(description) = max(description);
You can add these into the table using insert:
insert into skus (skuid, description)
select distinct left(skuid, 12) as skuid, 'New'
from skus;
If you just want a result set, then use union and the correct order by:
select skuid, description
from ((select skuid, description, 1 as priority
from skus
) union all
(select distinct left(skuid, 12) as skuid, 'New', 2
from skus
)
) sd
order by skuid, priority;

SQL displaying results as columns from rows

SQL Noob here.
I realize that many variations to this question have been asked but none seems to work or be fully applicable to my annoying situation, ie. I dont think PIVOT would work for what I require. I cant fathom the necessary words to google what I need efficiently.
I have the following query:
Select w.WORKORDERID, y.Answer
From
[SD].[dbo].[WORKORDERSTATES] w
LEFT JOIN [SD].[dbo].[WO_RESOURCES] x
ON w.workorderid = x.woid
Full Outer Join [SD].[dbo].ResourcesQAMapping y
ON x.UID = y.MAPPINGID
WHERE w.APPR_STATUSID = '2'
AND w.STATUSID = '1'
AND w.REOPENED = 'false'
It will bring back the following result:
+-----------+---------------------+
| WORKORDER | Answer |
+-----------+---------------------+
| 55693 | Brad Pitt |
| 55693 | brad.pitt#mycom.com |
| 55693 | Location |
| 55693 | NULL |
| 55693 | george |
+-----------+---------------------+
I would like all rows related to the value 55693 to output as columns like below:
+-----------+-----------+---------------------+----------+--------+--------+
| WORKORDER | VALUE1 | VALUE2 | VALUE3 | VALUE4 | VALUE5 |
+-----------+-----------+---------------------+----------+--------+--------+
| 55693 | Brad Pitt | brad.pitt#mycom.com | Location | NULL | george |
+-----------+-----------+---------------------+----------+--------+--------+
There will always be the same amount of values, and I am almost sure that the solution involves creating a temporary table but I cant get it to work any which way.
Any help would be greatly appreciated.
If you always have the same number of values (5) you can use a static PIVOT, otherwise you need a dynamic TSQL statement with PIVOT.
In both cases you'll need to add a column to guarantee rows/columns ordering otherwise there is no guarantee that you'll see the correct value in each column.
Here is a sample query thet uses a static PIVOT on 5 values (but remember to add a column to properly order the data replacing ORDER BY WORKORDER with ORDER BY YOUR_COLUMN_NAME):
declare #tmp table (WORKORDER int, Answer varchar(50))
insert into #tmp values
(55693, 'Brad Pitt')
,(55693, 'brad.pitt#mycom.com')
,(55693, 'Location')
,(55693, 'NULL')
,(55693, 'george')
select * from
(
select
WORKORDER,
Answer,
CONCAT('VALUE', ROW_NUMBER() OVER (PARTITION BY WORKORDER ORDER BY WORKORDER)) AS COL
from #tmp
) as src
pivot
(
max(Answer) for COL in ([VALUE1], [VALUE2], [VALUE3], [VALUE4], [VALUE5])
)
as pvt
Results:
Try to select another column that has different values as answer column and try to run pivot and that will work

How to get first n numbers from float

I have table A with two columns id(int) and f_value(float). Now I'd like to select all rows where f_value starts from '123'. So for the following table:
id | f_value
------------
1 | 12
2 | 123
3 | 1234
I'd like to get the second and third row. I tried to use LEFT with cast but that was a disaster. For the following query:
select f_value, str(f_value) as_string, LEFT(str(f_value), 2) left_2,
LEFT(floor(f_value), 5) flor_5, LEFT('abcdef', 5) test
from A
I got:
f_value | as_string | left_2 | flor_5 | test
------------------------------------------------
40456510 | 40456510 | | 4.045 | abcde
40454010 | 40454010 | | 4.045 | abcde
404020 | 404020 | | 40402 | abcde
40452080 | 40452080 | | 4.045 | abcde
101020 | 101020 | | 10102 | abcde
404020 | 404020 | | 40402 | abcde
The question is why left works fine for 'test' but for other returns such weird results?
EDIT:
I made another test I now I'm even more confused. For query:
Declare #f as float
set #f = 40456510.
select LEFT(cast(#f as float), LEN(4045.)), LEFT(404565., LEN(4045.))
I got:
|
------------
4.04 | 4045
Is there a default cast which causes this?
Fiddle SQL
Seems like your query is a bit wrong. The LEFT part should go in the WHERE-Clause, not the SELECT-part.
Also, just use LIKE and you should be fine:
SELECT f_value, str(f_value) as_string, LEFT(str(f_value), 2) left_2,
LEFT(floor(f_value), 5) flor_5
WHERE f_value LIKE '123%'
CREATE TABLE #TestTable(ID INT, f_value FLOAT)
INSERT INTO #TestTable
VALUES (1,22),
(2,123),
(3,1234)
SELECT *
FROM #TestTable
WHERE LEFT(f_value,3)='123'
DROP TABLE #TestTable
I hope this will help.
The replace get rid of the period in the float, by multiplying by 1 any 0 in front will be removed.
SELECT f_value
FROM your_table
WHERE replace(f_value, '.', '') * 1 like '123%'
I found the solution. The problem was that SQL Server uses the exponential representation of floats. To resolve it you need to first convert float to BigInt and then use Left on it.
Example:
Select * from A where Left(Cast(float_value as BigInt), 4) = xxxx
/*
returns significant digits from #f (a float) as an integer
negative sign is stripped off
*/
declare #num_digits int = 3; /* needs to be positive; accuracy diminishes with larger values */
with samples(num, f) as (
select 1, cast(123.45 as float) union
select 2, 123456700 union
select 3, -1.234567 union
select 4, 0.0000001234
)
select num, f,
case when f = 0 or #num_digits < 1 then 0 else
floor(
case sign(log10(abs(f)))
when -1 then abs(f) * power(10e0, -floor(log10(abs(f))) + #num_digits - 1)
when 1 then abs(f) / power(10e0, ceiling(log10(abs(f))) - #num_digits)
end
)
end as significant_digits
from samples
order by num;
sqlfiddle
Convert the FLOAT value to DECIMAL then to VARCHAR using CAST AND use LIKE to select the value starting with 4045.
Query
SELECT * FROM tbl
WHERE CAST(CAST(f_value AS DECIMAL(20,12)) AS VARCHAR(MAX)) LIKE '4045%';
Fiddle demo for reference