Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get lowercase data in SQL server

Tags:

sql-server

I have data like below in one of the column in table.

john;144;ny;
Nelson;154;NY;
john;144;NC;
john;144;kw;

I want to retrieve the rows which has lowercase in 3rd part of the data so i need to get

john;144;kw;
john;144;ny;

is possible to get the data like this?

like image 505
Abhiram Avatar asked Apr 29 '26 17:04

Abhiram


2 Answers

Force a case-sensitive matching, and then compare forced-lowercase to original:

SELECT ...
FROM ..
WHERE LOWER(name) = name  COLLATE Latin1_General_CS_AS
                                                 ^^---case sensitive

If the name is all-lower to start with, then LOWER() won't change it, and you'll get a match. If it's something like John, then you'd be doing john = John and the case-sensitivity will fail the match.

like image 191
Marc B Avatar answered May 01 '26 05:05

Marc B


This does not really answer your question, it certainly adds nothing to Marc's existing answer in terms of resolving your actual problem, it is merely meant as a demonstration of how simple it is to correct your design (this whole script runs in about a second on my local express instance of SQL Server 2012).

CREATE TABLE dbo.T
(
    ThreePartData VARCHAR(60)
);

-- INSERT 20,000 ROWS
INSERT dbo.T (ThreePartData)
SELECT  t.ThreePartName
FROM    (VALUES ('john;144;ny;'), ('Nelson;154;NY;'), ('john;144;NC;'), ('john;144;kw;')) t (ThreePartName)
        CROSS JOIN 
        (   SELECT  TOP (5000) Number = 1
            FROM    sys.all_objects a
                    CROSS APPLY sys.all_objects b
        ) n;
GO

-- HERE IS WHERE THE CHANGES START
/**********************************************************************/
-- ADD A COLUMN FOR EACH COMPONENT
ALTER TABLE dbo.T ADD PartOne VARCHAR(20),
                    PartTwo VARCHAR(20),
                    PartThree VARCHAR(20);
GO
-- UPDATE THE PARTS WITH THEIR CORRESPONDING COMPONENT
UPDATE  dbo.T
SET     PartOne = PARSENAME(REPLACE(ThreePartData, ';', '.') + 't', 4),
        PartTwo = PARSENAME(REPLACE(ThreePartData, ';', '.') + 't', 3),
        PartThree = PARSENAME(REPLACE(ThreePartData, ';', '.') + 't', 2);
GO

-- GET RID OF CURRENT COLUMN
ALTER TABLE dbo.T DROP COLUMN ThreePartData;
GO

-- CREATE A NEW COMPUTED COLUMN THAT REBUILDS THE CONCATENATED STRING
ALTER TABLE dbo.T ADD ThreePartData AS CONCAT(PartOne, ';', PartTwo, ';', PartThree, ';');
GO

-- OR FOR VERSIONS BEFORE 2012
--ALTER TABLE dbo.T ADD ThreePartData AS PartOne + ';' + PartTwo + ';' + PartThree + ';';

Then your query is as simple as:

SELECT  *
FROM    T
WHERE LOWER(PartThree) = PartThree  COLLATE Latin1_General_CS_AS;

And since you have recreated a computed column with the same name, any select statements in use will not be affected, although updates and inserts will need addressing.

like image 22
GarethD Avatar answered May 01 '26 05:05

GarethD