Select records with number in a string - tsql

I have a table [CLIData] containing phone numbers and corresponding customers:
Number Customer
01234567890 GeoffLtd
01234567891 FredLtd
01234567892 1JimLtd
01234567893 21DaveLtd
01234567894 297AhmedLtd
01234567895 FrankLtd
The customers that start with a numeric are part of Group1, customers that start with an alphabetic are part of Group2.
I am looking to create a query that will insert into another table [CustomerData] as below:
Number Group
01234567890 Group2
01234567891 Group2
01234567892 Group1
01234567893 Group1
01234567894 Group1
01234567895 Group2
Can someone help me with the WHERE on this? Is there a simple way to query where 1st character is numeric?
Thanks

INSERT INTO CustomerData(Number, [Group])
SELECT Number,
CASE WHEN ISNUMERIC(SUBSTRING(Customer, 1, 1)) = 1
THEN 'GROUP1'
ELSE 'GROUP2'
END [GROUP]
FROM CLIData
SQLFiddle Demo

Try this:
select
*
,gr = case when patindex('[0-9]%',customer)>0 THEN 'Group1' else 'Group2' end
from (
select '01234567890' as number,'GeoffLtd' as customer union all
select '01234567891','FredLtd' union all
select '01234567892','1JimLtd' union all
select '01234567893','21DaveLtd' union all
select '01234567894','297AhmedLtd' union all
select '01234567895','FrankLtd'
) x

Related

Postgress by a CASE with DISTINCT in select

I have a query like below getting the error - 'SELECT DISTINCT, ORDER BY expressions must appear in select list'
select distinct name
from fruits
order by case
when name = 'mango' then 1
else 2
end
This results 4 records, say
apple, mango, pear and grape
How can I make sure I get Mango as the first record always and the rest follow. I tried using the case statement, but not able to get the desired results. Any ideas will be appreciated.
I believe this should accomplish what you describe as needing.
select distinct
name,
case name when 'Mango' then 1 else 2 end as fruitOrder
from fruits
order by
fruitOrder
If you need to always have 'mango' in first position, no matter the other rows, this could be a way:
with fruits(name) as (
select 'apple' from dual union all
select 'mango' from dual union all
select 'pear' from dual union all
select 'grape' from dual
)
select name
from fruits
order by case
when name = 'mango' then 1
else 2
end
If you need to add a DISTINCT, this should work:
select distinct name,
case
when name = 'mango' then 1
else 2
end orderCol
from fruits
order by orderCol
This will give you 'Mango' followed by the others in order;
WITH get_rows AS
(SELECT DISTINCT item_type
FROM the_item)
SELECT item_type
FROM
(SELECT 1 as seq, item_type
FROM get_rows
WHERE item_type = 'Mango'
UNION ALL
SELECT 2 as seq, item_type
FROM get_rows
WHERE item_type <> 'Mango')
ORDER BY seq, item_type

Eliminating matching values in a SQL result set

I have a table with a list of transactions (invoices and credits) and I need to get a list of all the rows where the invoices and credits don't match up.
eg
user product value
bill ThingA 200
jim ThingA -200
sue ThingB 100
liz ThingC 50
I only want to see the third and fourth rows, as the values of the others match off.
I can do this if I select product, sum(value)
...
group by product
having sum(value) <> 0
which works well, but I want to return the user name as well.
As soon as I add the user to the select, I need to group by it as well, which messes it up as the amounts don't match up by user AND product.
Any ideas ? I am using MS SQL 2000...
Cheers
You can do like this:
SELECT tab2.user, product, sum_val
FROM
(SELECT product, SUM(value) sum_val
FROM your_table
GROUP BY product HAVING SUM(value) <> 0) tab1
INNER JOIN your_table tab2
ON tab1.product = tab2.product
#LolCoder solution is good, but given a context where you have "Thing B" with a "100" value by both "sue" and "liz", you could be able to retrieve the following resultset with my query :
| product | value | users |
+----------------------------+
| Thing B | 200 | sue, liz |
Here is the query :
select product
,sum(value) as value
,Stuff(( select ',' + convert(varchar(40), SQ.user)
from YourTable SQ
where Q.product = SQ.product
for xml path('')
), 1, 1, '') as users
from YourTable Q
group by Q.product

T-SQL how to count the number of duplicate rows then print the outcome?

I have a table ProductNumberDuplicates_backups, which has two columns named ProductID and ProductNumber. There are some duplicate ProductNumbers. How can I count the distinct number of products, then print out the outcome like "() products was backup." ? Because this is inside a stored procedure, I have to use a variable #numrecord as the distinct number of rows. I put my codes like this:
set #numrecord= select distinct ProductNumber
from ProductNumberDuplicates_backups where COUNT(*) > 1
group by ProductID
having Count(ProductNumber)>1
Print cast(#numrecord as varchar)+' product(s) were backed up.'
obviously the error was after the = sign as the select can not follow it. I've search for similar cases but they are just select statements. Please help. Many thanks!
Try
select #numrecord= count(distinct ProductNumber)
from ProductNumberDuplicates_backups
Print cast(#numrecord as varchar)+' product(s) were backed up.'
begin tran
create table ProductNumberDuplicates_backups (
ProductNumber int
)
insert ProductNumberDuplicates_backups(ProductNumber)
select 1
union all
select 2
union all
select 1
union all
select 3
union all
select 2
select * from ProductNumberDuplicates_backups
declare #numRecord int
select #numRecord = count(ProductNumber) from
(select ProductNumber, ROW_NUMBER()
over (partition by ProductNumber order by ProductNumber) RowNumber
from ProductNumberDuplicates_backups) p
where p.RowNumber > 1
print cast(#numRecord as varchar) + ' product(s) were backed up.'
rollback

Selecting distinct substring values

I have a field that is similar to a MAC address in that the first part is a group ID and the second part is a serial number. My field is alphanumeric and 5 digits in length, and the first 3 are the group ID.
I need a query that gives me all distinct group IDs and the first serial number lexicographically. Here is sample data:
ID
-----
X4MCC
X4MEE
X4MFF
V21DD
8Z6BB
8Z6FF
Desired Output:
ID
-----
X4MCC
V21DD
8Z6BB
I know I can do SELECT DISTINCT SUBSTRING(ID, 1, 3) but I don't know how to get the first one lexicographically.
Another way which seems to have the same cost as the query by gbn:
SELECT MIN(id)
FROM your_table
GROUP BY SUBSTRING(id, 1, 3);
SELECT
ID
FROM
(
SELECT
ID,
ROW_NUMBER() OVER (PARTITION BY SUBSTRING(ID, 1, 3) ORDER BY ID) AS rn
FROM MyTable
) oops
WHERE
rn = 1

sql: how to select a row with a true value from a column of boolean values after the HAVING clause

HI have 3 product tables, each with 3 columns namely customer name, and boolean optout and blacklist. After the Having clause, there will be 3 rows for each customer name (assuming he has all 3 products).
How do I output a true if any of the boolean columns contains a true. I figured out by using the cast operation below, but think there should be a more elegant solution.
SELECT customer_name,
cast(int4(sum(cast(optout As int4))) As Boolean) As optout,
cast(int4(sum(cast(blacklist As int4))) As Boolean) As blacklist
FROM
(SELECT * FROM product1
UNION SELECT * FROM product2
UNION SELECT * FROM product3) AS temp1
GROUP BY customer_name, optout, blacklist
HAVING optout=true or blacklist=true;
Try the bool_or aggregate function, sounds like exactly what you're looking for:
SELECT customer_name,
bool_or(optout) As optout,
bool_or(blacklist) As blacklist
FROM
(SELECT * FROM product1
UNION SELECT * FROM product2
UNION SELECT * FROM product3) AS temp1
GROUP BY customer_name, optout, blacklist
HAVING optout=true or blacklist=true;
If I have understood the question correctly I think you just need a CASE statement in the SELECT e.g.
CASE
WHEN blackLIST = TRUE OR optout = TRUE THEN 1
ELSE 0
END