not able Concat select Command - sql

select 'HP00'+ select CAST(select((select count(policyIdPolicy)
from #temp where policyIdPolicy Not like 'Hp%')-
(select count(policyIdPolicy) from #temp
where policyIdPolicy like 'Hp%')) AS VARCHAR(10))

Select each part separately and then concat.
Query
select 'HP00' + cast((t.col_1 - t.col_2) as varchar(max)) from(
select
sum(case when policyIdPolicy like 'Hp%' then 1 else 0 end) as col_1,
sum(case when policyIdPolicy not like 'Hp%' then 1 else 0 end) as col_2
from #temp
)t;

Try this:
select 'HP00'+
CAST
(
(
(select count(policyIdPolicy)
from #temp
where policyIdPolicy Not like 'Hp%'
)
-
(select count(policyIdPolicy)
from #temp
where policyIdPolicy like 'Hp%')
) AS VARCHAR(10)
)

Related

How to use case in pivot

I want to create a pivot of working hour by department and date.
I had a sql like
select department,sum(workinghours),date group by department,date.
then I write a pivot sql
select * from(
select department,sum(workinghours) as hours,date group by department,date
)as RC
PIVOT
(
sum(hours) for date
)as P
but this return lots of null value. so I update the pivot to
select * from(
select department,sum(workinghours) as hours,date group by department,date
)as RC
PIVOT
(
(case when sum(hours) is null then 0 else sum(hours) end) for date
)as P
then it has error.
I don't understand why, anyone can help?Thx.
You need to replace your null with some specific values in sum. As I have replaced 0 instead of null:
create table #t
(
Id int identity (1,1),
Department varchar (100),
WorkingHours int ,
Date datetime
)
Insert into #t (Department,WorkingHours,Date)
Select '1','10',GETDATE ()-1
Insert into #t (Department,WorkingHours,Date)
Select '1','20',GETDATE ()-1
Insert into #t (Department,WorkingHours,Date)
Select '1',null,GETDATE ()
select * from #t
select * from(
select department,sum(ISNULL(workinghours,0)) as hours,
cast (Year(date) as varchar) date
from #t
group by department,date
)as RC
PIVOT
(
sum(hours ) for date IN ([2018])
)as P
Try below with case when inside sum :
select * from(
select department,sum(workinghours) as hours,date group by department,date
)as RC
PIVOT
(
sum(case when hours is null then 0 else hours end) for date
)as P

MS SQL - How to order results by wildcard?

Query:
SELECT [Name]
FROM [dbo].[City]
where name like '%laus%'
Results:
How to order so records with leading wildcard (3,4) are first?
Your may try, but best way use full-text-search
SELECT [Name]
FROM [City]
where name like '%laus%'
ORDER BY
CHARINDEX('laus',name)
Try This
;WITH CTE(name )
AS
(
SELECT 'Berlin' UNION ALL
SELECT 'Laura' UNION ALL
SELECT 'Losangels' UNION ALL
SELECT 'Lausanne' UNION ALL
SELECT 'Lausen' UNION ALL
SELECT 'Roamanel' UNION ALL
SELECT 'Sankt Niklaus' UNION ALL
SELECT 'Vennes sur-Lausanne'
)
SELECT * FROM CTE
ORDER BY (CASE WHEN name like 'Laus%' THEN 1 END ) DESC
Result
name
--------
Lausanne
Lausen
Losangels
Laura
Roamanel
Sankt Niklaus
Vennes sur-Lausanne
Berlin
DECLARE #City TABLE(Name VARCHAR(32))
INSERT #City VALUES
('Belmont-sur-Lausanne'),
('Lausanne'),
('Lausen'),
('Le Mont-sur-Lausanne'),
('Berlin')
SELECT [Name]
FROM #City
--where name like '%laus%'
order by CASE WHEN PATINDEX('%laus%', name) = 0
THEN LEN(name)
ELSE PATINDEX('%laus%', name)
END
,name

Concatenate results in select

I am trying to insert values into a table that come from an other (lookup) table.
The first 3 results from the table are selected and need to be concatenated before they are inserted into an other table.
How can I alter the following insert to first concatenates them with no separation characters between the 3 names (example: JohnMaxLouise)?
INSERT INTO Table 2 VALUES ((SELECT TOP 3 names FROM Table1 ORDER BY NEWID()))
I am using SQL Server 2016 so string_agg is not available.
Personally, I think this is simplest with conditional aggregation:
INSERT INTO Table2
SELECT (MAX(CASE WHEN seqnum = 1 THEN name ELSE '' END) +
MAX(CASE WHEN seqnum = 2 THEN name ELSE '' END) +
MAX(CASE WHEN seqnum = 3 THEN name ELSE '' END)
)
FROM (SELECT name, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as seqnum
FROM (SELECT TOP 3 name
FROM Table1
ORDER BY NEWID()
) t
) t;
An alternative is an XML approach, but if you know you want three, then conditional aggregation (or pivot) works fine.
try the following:
declare #tab table (names varchar(max))
declare #tab1 table ([name] varchar(100))
insert into #tab1
select 'John' union select 'Max' union select 'Louise' union select 'xxx'
insert into #tab select (select top 3 [name] + '' from #tab1 for xml path(''))
select * from #tab
Thanks.
This will return '1,2,3,4'
DECLARE #x TABLE (i INTEGER)
DECLARE #r VARCHAR(255)
INSERT INTO #x VALUES (1),(3),(2),(4)
SELECT #r= STUFF(( SELECT ',' + CAST(i AS VARCHAR(max))
FROM #x
ORDER BY i
FOR XML PATH(''), type
).value('.','varchar(255)'), 1, 1, '')
SELECT #r
Solution Overview
You can use FOR XML PATH('') to achieve this, just use the following command:
SELECT '' + NAME
FROM (SELECT Top 3 NAME FROM TBL_1 ORDER BY NEWID()) AS T
FOR XML PATH('')
Or simple concatenation
SELECT #x = #x + NAME
FROM (SELECT Top 3 NAME FROM TBL_1 ORDER BY NEWID()) AS T1
Detailed Solution
SQLFiddle Demo
First i created the test environment using the following query
CREATE TABLE TBL_1 (NAME Varchar(50))
CREATE TABLE TBL_2 (NAME Varchar(50))
INSERT INTO TBL_1 (Name) VALUES ('John'),('Max'),('Louise'),('Mark'),('Peter')
Then i Used the following command
DECLARE #x varchar(255)
SELECT #x = (SELECT '' + NAME
FROM (SELECT Top 3 NAME FROM TBL_1 ORDER BY NEWID()) AS T1
FOR XML PATH('') )
INSERT INTO TBL_2(NAME) SELECT #x;
SELECT * FROM TBL_2
And the Result is JohnLouiseMax
Or you can use simple concatenation to achieve this
SQLFiddle Demo
DECLARE #x varchar(255)
SET #x = ''
SELECT #x = #x + NAME
FROM (SELECT Top 3 NAME FROM TBL_1 ORDER BY NEWID()) AS T1
INSERT INTO TBL_2(NAME) SELECT #x;
SELECT * FROM TBL_2

How To Check MAX value With a Pattern

For example,
I have output like this :-
ID
---
AB1
AB2
AB3
AB4
BD6
If I use MAX(ID), I will get 'BD6' But I want to check MAX Value For Pattern AB
How can I get that?
Simply filter the Data with ID field and then use Max():
EDIT: If ID contains number with more than 1 digits:
SELECT TOP 1 *
FROM
[Table] AS A
WHERE
RIGHT(ID, LEN(ID) - 2) = (SELECT
MAX(Cast(RIGHT(ID, LEN(ID) - 2) AS Int)) FROM [Table] WHERE ID LIKE 'AB%')
AND
ID LIKE 'AB%'
Try This. It will display all max ID for every String .
select CONCAT(ID,id1) as ID from
(
select left(id, patindex('%[^0-9]%', id) + 1) ID , max(cast(substring(id, PatIndex('%[0-9]%', id),len(id)) as numeric)) id1
from #Table
group by left(id, patindex('%[^0-9]%', id) + 1)
)a
For Specific ID value like 'AB' put value into where clause .
select CONCAT(ID,id1) as ID from
(
select left(id, patindex('%[^0-9]%', id) + 1) ID , max(cast(substring(id, PatIndex('%[0-9]%', id),len(id)) as numeric)) id1
from #Table
group by left(id, patindex('%[^0-9]%', id) + 1)
)a
where ID like '%ab%'
OutPut :
outpur for AB111
Check also live demo here.
Try it,
DECLARE #TABLE TABLE(ID VARCHAR(MAX))
INSERT INTO #TABLE (ID)
VALUES('AB1'),('AB2'),('AB3'),('AB4'),('AB11'),('AB111'),('XY112')
DECLARE #Prefix VARCHAR (10) = 'AB'
SELECT #Prefix + CAST(MAX(CAST(SUBSTRING(ID, (LEN(#Prefix) + 1),
(LEN(ID) - 2)) AS INT)) AS VARCHAR) AS ID FROM #TABLE WHERE ID LIKE
#Prefix +'%'
Try this :
SELECT 'AB' + CONVERT(NVARCHAR(10),MAX(CONVERT(INT, Nums.Numbers)))
FROM (SELECT Substring(ID, 3, 10) as Numbers
FROM #Tab tab
WHERE tab.ID LIKE 'AB%') as Nums
You can see this here => http://rextester.com/MAHKWE99983
Hope this helps!!!
You can get by this query.
create table temp
(
id varchar(10)
);
insert into temp values
('AB111'),
('AB1'),
('AB2'),
('AB3'),
('AB4'),
('BD6'),
('AB111')
;
declare #Pattern varchar(5)
set #Pattern='AB'
select distinct(Id) from temp where Id = #Pattern+convert(varchar(10),(
select MAX(Id) as Maximum from (
SELECT convert(integer,REPLACE( Id,#Pattern,'')) as Id FROM temp
where id like 'AB%'
)as test ))
with tmp as (
select 'AB1' id union all
select 'AB2' id union all
select 'AB3' id union all
select 'AB4' id union all
select 'AB111' id union all
select 'BD6' id
)
select top 1 * from tmp f1
where f1.ID LIKE 'AB%' and cast(SUBSTRING(f1.ID, 3, LEN(ID) -2) as integer) in
(
select max(cast(SUBSTRING(f2.ID, 3, LEN(ID) -2) as integer)) from tmp f2
WHERE f2.ID LIKE 'AB%'
)
SELECT MAX(ID) FROM #Tbl
GROUP BY LEFT(col_name,2)

SQL update column depending on other values in same column

I have a table similar to this:
Index Name Type
--------------------------------
1 'Apple' 'Fruit'
2 'Carrot' 'Vegetable'
3 'Orange' 'Fruit'
3 'Mango' 'Fruit'
4 'Potato' 'Vegetable'
and would like to change it to this:
Index Name Type
--------------------------------
1 'Apple' 'Fruit 1'
2 'Carrot' 'Vegetable 1'
3 'Orange' 'Fruit 2'
3 'Mango' 'Fruit 3'
4 'Potato' 'Vegetable 2'
Any chance to do this in a smart update query (= without cursors)?
You can run update with join to get row_number() within [type] group for each row and then concatenate this values with [type] using [index] as glue column:
update t1 set t1.[type] = t1.[type] + ' ' + cast(t2.[rn] as varchar(3))
from [tbl] t1
join ( select [index]
, row_number() over (partition by [type] order by [index]) as [rn]
from [tbl]
) t2 on t1.[index] = t2.[index]
SQLFiddle
Suppose that your table has a Primary Key called ID then you can run the following:
update fruits
set Type = newType
from
(
select f.id
,f.[index]
,f.Name
,f.[Type]
,Type + ' '+ cast((select COUNT(*)
from fruits
where Type = f.Type
and Fruits.id <= f.id) as varchar(10)) as newType
from fruits f
) t
where t.id = fruits.id
SELECT Index ,Name, Type, ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Index)AS RowNum
INTO #temp
FROM table_name
UPDATE #temp
SET Type = Type + ' ' + CAST(RowNum AS NVARCHAR(15))
UPDATE table_name
SET Type = t2.Type
FROM table_name t1
JOIN #temp t2 ON t2.Index = t1.Index
You can use the fact that you can update cte:
with cte as(select type, row_number() over(partition by type order by index) rn from table)
update cte set type = type + ' ' + cast(rn as varchar(10))