SQL: Select distinct - without highcase/lowcase duplicate - sql

My query:
SELECT distinct [ID], [IDGROUP], [DESCRIPTION]
FROM table
My result problem:
1, 1, Hello
1, 1, hello
How can I set a filter where I do not select duplicates where the difference is only the high/low case letter??

Try running this query.
SELECT distinct [ID], [IDGROUP], [DESCRIPTION] COLLATE SQL_Latin1_General_CP1_CI_AS FROM table
Here you are basically saying ignore case on the DESCRIPTION column
CI = Case insensitive
AS = Accent sensitive.

I guess mysql engine does not duplicate based on letter case by default.
That is both Hello and hello is considered same.

Not sure if this is the best way but this worked for me:
SELECT distinct [ID], [IDGROUP], Upper([DESCRIPTION]) as [DESCRIPTION]
FROM table

Related

sql repeat regex pattern unlimited times

I need to select where column contains numbers only and ends with a hyphen
I'm running SQL Server Management Studio v17.9.1
I have tried:
select * from [table] where [column] like '[0-9]*-'
select * from [table] where [column] like '[0-9]{1,}-'
select * from [table] where [column] like '[0-9]{1,2}-'
none of these work. The expression ([0-9]*-) works in any regex tester I've run it against, SQL just doesn't like it, nor the other variations I've found searching.
You can filter where any but the last character are not numbers and the last is a dash. DATALENGTH/2 assumes NVARCHAR type. If you're using VARCHAR, just use DATALENGTH
SELECT
*
FROM
[table]
WHERE
[column] like '%-'
AND
LEFT([column], (datalength([column])/2)-1) NOT LIKE '%[^0-9]%'
SQL Server does not support regular expressions -- just very limited extensions to like functionality.
One method is:
where column like '%-' and
column not like '%[^0-9]%-'
You can use left() and right() functions as below :
with [table]([column]) as
(
select '1234-' union all
select '{123]' union all
select '1234' union all
select '/1234-' union all
select 'test-' union all
select '1test-' union all
select '700-'
)
select *
from [table]
where left([column],len([column])-1) not like '%[^0-9]%'
and right([column],1)='-';
column
------
1234-
700-
Demo

How to split a column into two columns based on the value in the another column

I have below data in the Ms SQL server table.
I would like to get the output like below.
I have tried two sets of queries but it didn't helped me.
1st set query gives me the null values
Query
SELECT
[id]
, [sav]
, [cat]
, [tech]
, [asset]
, CASE
WHEN [objname] = 'FieldName'
THEN [stringvalue]
END AS [fieldname]
, CASE
WHEN [objname] = 'FieldValue'
THEN [stringvalue]
END AS [fieldvalue]
FROM [test].[dbo].[sample];
Output
2nd set query gives me 0 as field value, because i have hard coded it.
Query
SELECT
ROW_NUMBER() OVER(ORDER BY [fieldname]) AS 'id'
, [sav]
, [cat]
, [tech]
, [asset]
, [fieldname]
, 0 AS [fieldvalue]
FROM [test].[dbo].[sample] PIVOT(MAX([stringvalue]) FOR [objname] IN(
[fieldname])) [p]
WHERE [fieldname] IS NOT NULL;
Output
How to achieve it ?
You have a very arcane data structure. SQL tables are inherently unordered. From what I can tell, the SQL value is in the "next" row based on the id.
If so, you can use lead():
select . . .,
stringvalue as fieldname, next_string_value as stringvalue
from (select t.*, lead(t.stringvalue) over (order by id) as next_string_value
from t
) t
where t.objname = 'objname';
If you are really using SQL Server 2008, you can use a self-join. This does assume that the ids have no gaps in them.

get number of rows select statement will fetch (without real fetching)

Lets say I have many sql statements like this one:
select *
from [A]
where a in (
select a
from [B]
where b = 'c'
)
order by d;
Since my database is huge, I just need to determine how many rows this query will fetch. Of course I can really fetch all rows and count it but my intention is to avoid fetching since that would be a big overhead.
I have tried to extend query as follows:
select count (*)
from (
select *
from [A]
where a in (
select a
from [B]
where b = 'c'
)
order by d
) as table;
That works fine for some tables but for some (like this one in example) SQL server throws this:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.
Consider that I'm not allowed to change any original query, I can just extend it...
Any idea?
Thanks.
EDIT: I'm pretty sure there is some solution related to ##ROWCOUNT field, but not sure how to use it...
Just remove the order by in the subquery. It doesn't affect the number of rows:
select count(*)
from (select *
from [A]
where a in (select a from [B] where b = 'c')
) as table;
Actually, this is better written as:
select count(*)
from [A]
where a in (select a from [B] where b = 'c')
That is, just replace the select * with select count(*).
Finally, if you have to keep the queries the same, then use top 100 percent:
select count(*)
from (select top 100 percent *
from [A]
where a in (select a from [B] where b = 'c')
order by d
) as table;
This does require changing the original queries, but in a way that does not affect what they output and does allow them to be used as ctes/subqueries.
You are allowed to use order by in subqueries when you also use top.
EDIT:
If you are using dynamic SQL, you might have to do something like:
#sql = 'select count(*) from (' +
(case when #sql not like 'SELECT TOP %'
then stuff(#sql, 1, 7, 'SELECT top 100 percent')
else #sql
end) +
+ ')';
The logic could be a bit more complicated if your SQL is not well formatted.

Select Rows Where A Column Contains Any Result From A SubQuery

If have a table that contains a column of concatenated data using a delimiter i.e. 11111_22222_33333 (I know this is bad practice, but that's the data I have to work with)
I need to write a query that returns all rows that contain specific values of 22222 where the specific values are the result of a sub query.
So, what I am doing is follows...
SELECT * FROM myTable WHERE myColumn IN (SELECT [Name] FROM subTable)
This runs but doesnt return any results as it's specifically matching 1111_2222_3333 to 2222. So what I need is a way of using a LIKE or something similar
SELECT * FROM myTable WHERE myColumn LIKE (SELECT [NAME] FROM subTable)
gives the error
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows
=, !=, <, <= , >, >= or when the subquery is used as an expression.
How would this be accomplished please? I am using Sql Server 2008 R2 to develop, but the solution needs to also be compatible with Server 2005
Your subquery is returning more than one value and LIKE will not work with subquery, what you need to use is EXISTS here try this
SELECT * FROM myTable a
WHERE EXISTS (SELECT 1 FROM subTable b
WHERE a.myColumn LIKE '%' + b.[NAME] + '%')
SELECT
t1.*
FROM myTable t1
join (
SELECT distinct [Name] FROM subTable
) x
on t1.myColumn like '%' + x.[name] + '%'
You can use a JOIN with the LIKE clause to get the result:
select *
from mytable t
inner join subtable s
on t.mycolumn like '%'+s.name+'%'
See SQL Fiddle with Demo

SQL. How should i write NOT LIKE statement

SELECT *
FROM [Table]
WHERE (Izdava NOT LIKE NULL)
// how to check if Izdava is not NULL
This should work:
SELECT * FROM [Table] WHERE Izdava IS NOT NULL
SELECT * FROM [Table] WHERE (Izdava IS NOT NULL)
LIKE NULL is meaningless. It doesn't make sense. LIKE is used for comparing a partial string using wildcards, or a complete string without wildcards.
Depending on the RDBMS you want NOT IS NULL,
SELECT * FROM [Table] WHERE (NOT Izdava IS NULL)
I think this is what you want.
SELECT *
FROM [Table]
WHERE Izdara Is Not NULL
Information about NULL values from MSDN:
Following is information about nulls:
To test for null values in a query, use IS NULL or IS NOT NULL in the
WHERE clause.
If you are checking for not null, dont use the like clause. Just write
select * from tablename where columnmame is not null
If it's MSSQL or Oracle then do this:
SELECT *
FROM [Table]
WHERE Izdava IS NOT NULL