How to select convert and sum from database? - sql

I have a column price datatype is nvarchar because I save thousand seperator with comma like 1,000,000.00. I now need to select convert and sum it in select statement then display group by id in crystalreport.
My select statement:
select id,productname,type,price,datesell,seller from tb_billdetail group by id
Here I need how to convert the price from nvarchar to type double and sum it after converted but just using select statement?
Something I need to display in crystal report like:
col_id col_name col_type col_price col_date
**001**
001 fish food 20,000.00 01/02/2018
001 fish food 10,000.00 10/02/2018
col_sum id 001: 30,000.00
next group id 002 and 003 ....

Declare #tt table (name nvarchar(10), value nvarchar(10))
insert into #tt (name, value) values ('a', '1,000')
insert into #tt (name, value) values ('a', '1,10,000')
insert into #tt (name, value) values ('b', '2,000.4223')
insert into #tt (name, value) values ('b', '4,000.2')
select name, sum(cast(REPLACE(value,',','') as float)) as sum from #tt group by name
it's not a good idea to store with comma separate, store it's as the decimal.
If your storing comma for displaying purpose then add it when displaying.

Related

How to handle Multivalue attribute in sql server

I have a table in Data warehouse.
Create table customer
(
id int,
name varchar(30),
address varchar(50)
);
let data in table
insert into Customer values(1, 'Smith', 'abc,def, lkj');
insert into Customer values(2, 'James', 'pqr,lmn');
i want to split the table address column and insert new row if we have many values. Like
1 Smith abc
1 Smith def
1 Smith lkj
2 James pqr
2 James lmn
i have data of 100000 recrds, please help me in this regards.
You can use string_split() and adjust the insert statement:
insert into Customer (id, name, address)
select v.id, v.name, s.value
from (values (1, 'Smith', 'abc,def,lkj')
) v(id, name, address) cross apply
string_split(v.address, ',') s;
You might also want to add a check constraint on address so it does not contain a comma.
You would load from a staging table to the final table by doing:
insert into Customer (id, name, address)
select t.id, t.name, s.value
from staging t cross apply
string_split(v.address, ',') s;

SQL - INSERT AND UPDATE Table from a Temp Table

I am trying to insert some data into a Temp Table(#temptable) and after inserting I would Like to perform Sum(amount) which matches the same ID and group by the cust name and the bill ID and I want to select the earliest date available in those matching ID. After all these Operations I would like to update the original table(billtable)
Bill ID Amount CUstName Duedate
12 12.2 ABC 12222016
12 22.2 ABC 12112016
13 23.22 ABC 12102016
Bill ID Amount CUstName Duedate
12 34.4 ABC 12112016
13 23.22 ABC 12102016
you will need something like the below
If(OBJECT_ID('tempdb..#t') Is Not Null)
Begin
Drop Table #t
End
create table #t
(
billid varchar (50),
amount decimal,
cust varchar (50),
duedate datetime
)
insert into #t (billid,amount,cust,duedate) values ('12',12.2,'abc','20161222')
insert into #t (billid,amount,cust,duedate) values ('12',22.2,'abc','20161211')
insert into #t (billid,amount,cust,duedate) values ('13',23.22,'abc','20161210')
insert into #t (billid,amount,cust,duedate) values ('12',34.4,'abc','20161211')
insert into #t (billid,amount,cust,duedate) values ('13',23.22,'abc','20161210')
select billid,sum(amount),MIN(duedate)
from #t
group by billid

I need sql query for order by values of given parameters?

I need a query for order by given parameters
My table like this
ID Name Type
1 Argentine Standard
2 Spain Critical
3 France Critical
4 Germany Standard
5 Brazil Standard
6 Italy Standard
I am sending the parameter as Germany,Spain,Brazil,Argentine my output should be
ID Name Type
4 Germany Standard
2 Spain Critical
5 Brazil Standard
1 Argentine Standard
At present i used in query and i got the output in order by id that means it shows the result as in database order but i need to order by query parameter order?
can anyone help me for query?
according to your output I can suggest you this query. You can also alter order by clause as per your requirement:
select id,name,type from stack where name in('Germany','Spain','Brazil','Argentine') order by type,name,id desc
may be you are sending Comma Separated Input then we can convert them into rows and join with the table Data to get Required Output.
declare #t varchar(50) = ' Germany,Spain,Brazil,Argentine'
Declare #tt table (ID INT IDENTITY(1,1),val varchar(10))
insert into #tt (val)
SELECT
LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Certs
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE(#t,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)
DECLARE #Table1 TABLE
(ID int, Name varchar(9), Type varchar(8))
;
INSERT INTO #Table1
(ID, Name, Type)
VALUES
(1, 'Argentine', 'Standard'),
(2, 'Spain', 'Critical'),
(3, 'France', 'Critical'),
(4, 'Germany', 'Standard'),
(5, 'Brazil', 'Standard'),
(6, 'Italy', 'Standard')
;
select T.ID,TT.val,T.Type from #Table1 T
INNER JOIN #tt TT
ON T.Name = TT.val
ORDER BY TT.ID

Query to display output horizontally

I need to display a query output in a horizontal manner. I have some example data
create table TestTable (id number, name varchar2(10))
insert into TestTable values (1, 'John')
insert into TestTable values (2, 'Mckensy')
insert into TestTable values (3, 'Valneech')
insert into TestTable values (4, 'Zeebra')
commit
select * from TestTable
This gets the output in a vertical view.
ID Name
==========
1 John
2 Mckensy
3 Valneech
4 Zeebra
However, I need to display it horizontally.
ID 1 2 3 4
Name John Mckensy Valneech Zeebra
How can one do this?
To pivot, you should use the pivot clause of the select statement:
select *
from testtable
pivot ( max(name)
for id in (1,2,3,4)
)
This is not particularly pretty to do in SQL, so you should consider carefully whether this is what you want to do. I normally use Oracle Base for pivoting examples but there are many out there.
Here's a little SQL Fiddle to demonstrate.
Maybe it will help you:
select 'id', LISTAGG(id, ' ') WITHIN GROUP (ORDER BY name)
from testtable
union
select 'name', LISTAGG(name, ' ') WITHIN GROUP (ORDER BY name)
from testtable
EDIT:
or with pivot:
create table TestTable2 (id varchar2(30), name varchar2(10));
insert into TestTable2 values ('id', 'name');
insert into TestTable2
select cast(id as varchar2(30)) as id , name
from testtable
select *
from testtable2
pivot ( max(name)
for id in ('id',1,2,3,4)
)
PIVOT operator is what you are looking for.

SQL Server Simple Group by query

I have a simple problem , Although i believe its simple , am not able to figure out the same.
Consider i have the below table with exactly same data as given below :
CREATE TABLE #temp
(
link varchar(255),
number INT,
fname varchar(255)
)
insert into #temp VALUES ('abc',1,'f1')
insert into #temp VALUES ('abc',2,'f2')
insert into #temp VALUES ('abc',3,'f3')
insert into #temp VALUES ('abc',4,'f6')
insert into #temp VALUES ('abc',10,'f100')
insert into #temp VALUES ('abe',-1,'f0')
insert into #temp VALUES ('abe',1,'f1')
insert into #temp VALUES ('abe',2,'f2')
insert into #temp VALUES ('abe',3,'f3')
insert into #temp VALUES ('abe',4,'f6')
insert into #temp VALUES ('abe',20,'f200')
insert into #temp VALUES ('cbe',-1,'f0')
insert into #temp VALUES ('cbe',1,'f1')
insert into #temp VALUES ('cbe',2,'f2')
insert into #temp VALUES ('cbe',3,'f3')
Now for a given link , i need to get the max 'number' and the corresponding 'fname' which has the max 'number' for the given 'link'.
1)Ex : if link is 'abc' , output should be
abc, 10, f100
2)Ex : if link if 'abe' , Output should be
abe, 20, f200
3)Now link can be also given as a pattern , like (link like 'ab%') , so output should be
abc, 10, f100
abe, 20, f200
4)if (link like 'cb%') , so output should be
cbe, 3, f3
Any help in writing this group by query. I have a solution using CAST and string concat like below , but that seems to be in-efficient.
select link,number,fname from #temp
where link like 'ab%' and link+'_'+CAST(number AS varchar(255))
in (select link+'_'+CAST(MAX(number) AS varchar(255)) from #temp
group by link)
Thanks..
Using a self join:
SELECT x.link,
x.number,
x.fname
FROM #temp x
JOIN (SELECT t.link,
MAX(t.number) AS max_number
FROM #temp t
GROUP BY t.link) y ON y.link = x.link
AND y.max_number = x.number
Using a CTE and ROW_NUMBER (SQL Server 2005+):
WITH cte AS (
SELECT x.link,
x.number,
x.fname,
ROW_NUMBER() OVER(PARTITION BY x.link
ORDER BY x.number DESC) rank
FROM #temp x)
SELECT c.link,
c.number,
c.fname
FROM cte c
WHERE c.rank = 1