Generate Alpha numeric series in SQL Server 2008 - sql

Can anyone please help me on this?
I want to generate a alpha numeric series like A.1, A.2, A.3, A.4, B.1, B.2 which should increment automatically if I add new row.
I have a columns A and B which will be look like below.
A B
-----
1 A
1 A
1 A
1 A
2 B
2 B
3 C
3 C
3 C
The result must be look like below:
A B C
-----------
1 A A.1
1 A A.2
1 A A.3
1 A A.4
2 B B.1
2 B B.2
3 C C.1
3 C C.2
3 C C.3

The below query can return your expected result.
SELECT A, B, B + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY B ORDER BY A) AS VARCHAR) AS C
FROM TableName
Generating the Alpha numeric series is difficult. Using ROW_NUMBER() in computed column is also not possible. So for your case view is the right choice to achieve your expectation:
CREATE VIEW dbo.vw_MyAlphaNumbericOrder AS
SELECT A, B, B + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY B ORDER BY A) AS VARCHAR) AS C
FROM dbo.TableName
So when ever you are inserting a new record, then SELECT * FROM dbo.vw_MyAlphaNumbericOrder will return with the alpha numeric series as column C.
Sample execution with the given sample data:
DECLARE #TestTable TABLE (A INT, B VARCHAR (2));
INSERT INTO #TestTable (A, B) VALUES
(1, 'A'),
(1, 'A'),
(1, 'A'),
(1, 'A'),
(2, 'B'),
(2, 'B'),
(3, 'C'),
(3, 'C'),
(3, 'C');
SELECT A, B, B + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY B ORDER BY A) AS VARCHAR) AS C
FROM #TestTable

We can achieve this by below statement:
Select A,B,concat(B,'.',cast(row_number() over(partition by B order by B) as char(32))) as C
1.row_number() over (Partition by)-- will generate new row no. in each category of column B.
2.Cast -- will change the numeric value to character value where 32 specifies the length of data the field can hold
3. Concat-- will concatenate the required columns to create Alpha-numeric string

Related

Compare values within a column per partition

I'm looking to compare values within a column per partition and see if they match but I'm not sure how to go about it.
A
B
C
22
900
0
24
900
0
22
006
1
24
006
1
Basically I want to check if the values for column A match the values for column A per partition of C.
So in this case the values for column A in the first partition of C (value 0) are 22 and 24
the values for column A in the second partition of C (value 1) are also 22 and 24. in this case there is a match. Is there a way to complete this comparison (and possibly put it in a new column with 1=match and 0=no match?
So trying to Help, I tried this on Postgres.
I think you'll find a way to adapt this sql to terrada's.
-- Lets create a table of your data (and more)
create table mydata (a integer, b integer, c integer);
insert into mydata (a, b, c) values (22, 900, 0);
insert into mydata (a, b, c) values (24, 900, 0);
insert into mydata (a, b, c) values (22, 900, 1);
insert into mydata (a, b, c) values (24, 900, 1);
insert into mydata (a, b, c) values (22, 900, 2);
insert into mydata (a, b, c) values (22, 900, 3);
insert into mydata (a, b, c) values (21, 900, 2);
-- Here below the solution
SELECT c,
CASE
when COUNT(c) OVER(PARTITION BY conc) = 1 Then 0
when COUNT(c) OVER(PARTITION BY conc) > 1 Then 1
END as flag
FROM
( SELECT c, STRING_AGG (a::text, ',') conc
FROM mydata
GROUP BY c ) sub1
I guess now you have idea how to do ;)

Get last value based on a condition on ordered table in SQL

I have a table representing product groups. Groups are defined by row number and their Type. Hence here we have 2 groups, the group is defined by the Type A, the Type B being components.
Row number
Type
0
A
1
B
2
B
3
A
4
B
5
B
With just this data, I need to find back the row number of the last preceeding Type A occurence :
Row number
Type
Row father
0
A
0
1
B
0
2
B
0
3
A
3
4
B
3
5
B
3
I can't find a way to get this. It's a sort of lag() or first_value() based on condition. Here I have 2 groups of 2 components, but I can have more groups with different sizes. The only thing that defines the group are the row number : every row number under Type A (so with Type B) is a child of the above Type A, until next type A.
Thank you for your help
You can achieve the desired result by using a join in conjunction with a group-by.
Test Data
CREATE TABLE TEST (ROW_NUMBER integer, TYPE varchar(1));
INSERT INTO test VALUES (0, 'A');
INSERT INTO test VALUES (1, 'B');
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'A');
INSERT INTO test VALUES (4, 'B');
INSERT INTO test VALUES (5, 'B');
Query
SELECT T.*, MAX(A.ROW_NUMBER) AS ROW_FATHER
FROM TEST T
LEFT JOIN TEST A
ON A.TYPE = 'A' AND a.ROW_NUMBER <= T.ROW_NUMBER
GROUP BY T.ROW_NUMBER, T.TYPE
ORDER BY T.ROW_NUMBER
Result

SQL Server SSRS Multiple lookup values

I have a huge set of data. Some pf the data has multiple values, kinda looking like this:
Column 1 Column 2
A 1
A 10
A 1E
B 2F
B 1BH
C WBH
D 3X
D 2
D 1
D 10
D 11
I would like to select the unique values in Column 1 and display all relevant values of Column 2 in as string separated by comma (using SSRS). i.e.
Column 1 Column 2
A 01, 10, 1E
B 2F, 1BH
C WBH
D 02, 01, 10, 11
In addition, any value in Column 1 that is less than 10, I would like it to be preceded by a zero.
I know I can use SELECT DISTINCT to get all unique values of Column 1. But I am unsure how to go around Column 2?
With regards to having a zero preceding numbers less than 10, I can do this:
SELECT RIGHT('0' + convert(varchar(2), value()), 2)
I am unsure how to put it all together to get the result I want.
Thank you.
I think this is what you want.
DECLARE #Input TABLE
(
ProductID INT,
Price INT
)
INSERT INTO #Input VALUES (6,22), (6,35), (6,77), (6, 88), (6,55),(6,200),(7,6),(7,4),(8,5),(8,5)
;WITH CTE AS
(SELECT ProductID, MAX(Price) AS Max_Price, MIN(Price) AS Min_Price
FROM #Input
GROUP BY ProductID
)
SELECT ProductID, CASE WHEN Max_Price > Min_Price THEN CONVERT(VARCHAR(10), Min_Price) + ', ' + CONVERT(VARCHAR(10),Max_Price)
ELSE CONVERT(VARCHAR(10), Min_Price) END AS Price_Range
FROM CTE

How to return one row from group by multiple columns

I am trying to extract a list of unique customers from a database where some customers are listed more than once. The (almost) duplicate rows exist because customers have been moved from one division to another or because the customers have been registered with another address (or both).
So my challenge is in data that looks something like this:
ID Customer Division Address
-----------------------------------
1 A M X
1 A L X
2 B N Y
2 B N Z
3 C P W
3 C T S
I want my select statement to return one row for each customer (I dont care which one).
ID Customer Division Address
-----------------------------------
1 A M X
2 B N Y
3 C P W
I am using SQL Server 2008. I think I need to do a "GROUP BY" the last two columns but I don't know how to get just one row out of it.
I hope someone can help me!
(Yes, I know the problem should be solved at the source but unfortunately that is not possible within any reasonable time-frame...).
select ID, Customer,Division, Address from
(
SELECT
ID, Customer,Division, Address,
ROW_NUMBER() OVER (PARTITON BY Customer Order by Id) as RN
FROM T
) t1
WHERE RN=1
Try this one -
DECLARE #temp TABLE
(
ID INT
, Customer CHAR(1)
, Division CHAR(1)
, [Address] CHAR(1)
)
INSERT INTO #temp (ID, Customer, Division, [Address])
VALUES
(1, 'A', 'M', 'X'),
(1, 'A', 'L', 'X'),
(2, 'B', 'N', 'Y'),
(2, 'B', 'N', 'Z'),
(3, 'C', 'P', 'W'),
(3, 'C', 'T', 'S')
SELECT t.id
, t.Customer
, t.Division
, t.[Address]
FROM
(
SELECT *
, rn = ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY 1/0)
FROM #temp
) t
WHERE T.rn = 1
SELECT ID, Customer, Division = MAX(Division), [Address] = MAX([Address])
FROM #temp
GROUP BY ID, Customer
Output -
id Customer Division Address
----------- -------- -------- -------
1 A M X
2 B N Y
3 C P W
ID Customer Division Address
----------- -------- -------- -------
1 A M X
2 B N Z
3 C T W

SQL respect order rows in IN clause

I have a table like this:
CREATE TABLE A
(
pk int,
fk int,
col text,
sort_index int
)
and I have a query like this:
select b.fk from A where A.col in ('a','b', 'c')
group by b.fk
but I want only the b.fk that contains all elements in IN clause in order (using the column sort_index).
Is this possible with SQL? If so, how? (Oracle)
For example, I have this data
pk fk col sort_index
1 1 a 1
2 1 c 2
3 1 b 3
4 2 a 1
5 2 b 2
6 2 c 3
I want just the fk 2 because it havs all col in IN and respect the order.
In case you can modify the IN values before executing the query , then this query may work.
SELECT DISTINCT A1.FK
FROM A A1
WHERE A1.COL IN ('a', 'b', 'c')
and (SELECT WM_CONCAT(A2.COL)
FROM A A2
WHERE A2.FK = A1.FK) = 'a,b,c'
For this you will have to pass the IN values as comma separated quoted values('a', 'b', 'c') and only comma separated values (a,b,c).
Hope it helps