How to get unique value from sql table based on charachter length of value - sql

Here I have two columns like below example column1 & column2 in sql table and i want to get unique value row on the basis of column2 column value from table
Below example of dummy table
Column1 Column2
---------- -------------
1001 ab
1001 abc
1001 abcd
2001 wxyz
2001 wxy
2001 wx
In above example value starting from a & another value starting from w in Column2
On the basis of same value character length, i want to get result like below
Output:
Column1 Column2
---------- -----------
1001 abcd
2001 wxyz
Thanks in advance of help :)

If I understood you correctly, you want the highest length (you didn't say what to do when there are two with the same length) but basically you want something like this:
SELECT * FROM YourTable
WHERE (column1,len(column2)) IN(select Column1,max(len(column2))
FROM YourTable
GROUP BY Column1)

If you are looking if your values in column2 are somewhere included in other rows, in other words: If you are looking for rows with combinations of characters which are unique on their own, this might be your solution:
CREATE TABLE TestTable(Column1 INT,Column2 VARCHAR(100));
INSERT INTO TestTable VALUES
(1001,'ab')
,(1001,'abc')
,(1001,'abcd')
,(2001,'wxyz')
,(2001,'xyz')
,(2001,'yz');
SELECT *
FROM TestTable
WHERE NOT EXISTS(SELECT 1
FROM TestTable AS x
WHERE x.Column1=TestTable.Column1
AND LEN(x.Column2)>LEN(TestTable.Column2)
AND x.Column2 LIKE '%' + TestTable.Column2 + '%'
)
DROP TABLE TestTable;

Related

Union columns and remove blanks

I have a table which appears like this (I've shortened it for example purposes)
no no19 no68
3387034694344500
3387452540705400
3388486878919450
3371522572594880
3372232397709690
3373608476884750
3382142940562320
3382142940562320
3383084144363070
so no, no19 and no68 are 3 different columns, but the data in column 'no19' starts in the next row after data in column 'no' ends.
As between these columns I have a lot more data, I would like to create a readable table. I have merged these columns into one, using this code:
CREATE TABLE MULTICURRENCY_CHECK
(
TOKEN varchar(255)
)
INSERT INTO MULTICURRENCY_CHECK
(
TOKEN
)
SELECT no FROM book1
UNION ALL
SELECT no19 FROM book1
UNION ALL
SELECT no68 FROM book1
The problem is, the result I got looks like this:
TOKEN
3387034694344500
3387452540705400
3388486878919450
3371522572594880
3372232397709690
3373608476884750
3382142940562320
3382142940562320
3383084144363070
So there are blank rows between in column TOKEN. I've tried to delete them, but it by simple delete command but it's not working (tried those two below):
delete from multicurrency_check where TOKEN = ' '
delete from multicurrency_check where TOKEN is NULL
Perhaps there is a different way I should deal with this table, maybe quicker? As the original table looks like these (just sample data)
no a b no19 c d no68
3387034694344500 data1 data4
3387452540705400 data2 data5
3388486878919450 data3 data6
3371522572594880 data7 data10
3372232397709690 data8 data11
3373608476884750 data9 data12
3382142940562320
3382142940562320
3383084144363070
so what I would like to have in the end is table like this:
| TOKEN | a | b | c | d
where token is a merge of no, no19 and no68, and then folowwing a,b,c,d columns with data matching appropriate id from TOKEN column (a,b,c,d can be null)
You could delete them in your UNION query like:
SELECT no FROM table WHERE no IS NOT NULL
UNION
SELECT no19 FROM table WHERE no19 IS NOT NULL
UNION
SELECT no68 FROM table where no68 IS NOT NULL
You could also use COALESCE() instead of union since a column only contains data when the other's are null:
SELECT COALESCE(no, no19, no68) FROM table
Instead of putting these values in their own table, you could start with the above queries and build off of them. Say you want to also bring in A,B or C,D into the results:
SELECT COALESCE(no, no19, no68) as newno, COALESCE(a,c) as ac, COALESCE(b,d) as bd FROM table;
As to why your DELETE didn't work, perhaps those NULL's aren't NULL. Perhaps they hold a TAB character or 50 spaces? In which case #sidux's comment on your Q would do the trick. Trimming the field and looking where its value is =''.
Maybe something like this:
select
isnull(no,'')+isnull(no19,'')+isnull(no68,''),
a,b,c,d
from book1
That should concatenate all token in a row (and only one from no, no19 and no68 will have a value).
I created a table 'foo' with 3 text columns, like so:
column1 column2 column3
------- ------- -------
row1 3371522572594880 3373608476884750
row2 asdfasdf asdfasdf
row3 3387452540705400 3388486878919450
Then executed the query
select token from(
select column1 as token from foo where column1 != ''
union all
select column2 as token from foo where column2 != ''
union all
select column3 as token from foo where column3 != ''
)
And got the result:
token
3371522572594880
asdfasdf
3387452540705400
3388486878919450
3373608476884750
asdfasdf
Is that what you're after?

SQL Server : Nested Select Query

I have a SQL query returning results based on a where clause.
I would like to include some more results, from the same table, dependent on what is found in the first select.
My select returns rows with ID's that meet the where criteria. It does happen that the table has more rows with this ID, but that does not meet the initial where criteria. Rather than re querying the DB with a separate call, I would like to use one select statement to also get these extra rows with the same ID. ID is not the index/ID. Its a naming convention I am using here.
Pseudo: (two steps)
1: select * from table where condition=xxx
2: for each row returned, (select * from table where id=row.id)
I want to do:
select
id as thisID, field1, field2,
(select id, field1, field2 from table where id = thisID)
from
table
where
condition=xxx
I have multiple joins in my real query, and just cant get the above to work. I unfortunately can not supply the real query, but I get an error of:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. Invalid column name 'thisID'
My query works fine with the multiple joins, without the above. I am trying to retrieve these extra records as part of the current working query.
Example:
TABLE
select * from table where col3 = 'green'
id, col1, col2, col3
123 | blue | red | green
-------------------------
567 | blue | red | green
-------------------------
123 | blue | red | blue
-------------------------
890 | blue | red | green
-------------------------
I want to return all 4 rows, because although row 3 fails the where condition, it has the same col1 value as row 1 (123), and I need to include it, as it is part of a "set" that I need to locate / import, called / referenced by id=123.
What I am doing manually now, is getting row one, and then running another query based on row 1's ID, to get row 3 as well.
You can use Where IN
select id as thisID, field1, field2 from table
where id in
(select id from table where condition=xxx)
Try this
Let say you table is below and called #Temp
Id Col1 Col2 Col3
123 blue red green
567 blue red green
123 blue red blue
890 blue red green
Will get the id to a temp table
Create Table #T1(Id int)
Insert Into #T1
Select Id
From #Temp
Where Col3='green'
Then
Select distinct *
From #Temp
Where Id in (select Id from #T1) Or Col3='Green'
Which result all the rows from main table
Update
If you want to use the way you currently using, try something like below
select
id as thisID, field1, field2,
(select top 1 id from table where id = t.id) as Id,
(select top 1 field1 from table where id = t.id) as field1,
(select top 1 field2 from table where id = t.id) as field2,
from
table t
where
condition=xxx

Create duplicates with sql

This might sound a bit confusing at first. But I have a table with data and I want to create duplicates of all the rows in this table. So, if i do:
SELECT *
FROM the_table
it lists all the data in this table. Now, i want to create a copy of all returned results, except for that I want to change data for one column (the date). This will make the new rows unique.
The reason I want to do this is because I want more data in this table since im building statistics out of it for testing purposes. So, if I have this:
**Column1 Column2 Column3**
abc aaa bbb
abcd aaaa bbbb
abcde aaaaa bbbbb
The table will now contain:
**Column1 Column2 Column3**
abc aaa bbb
abcd aaaa bbbb
abcde aaaaa bbbbb
abc aaa bbb_new
abcd aaaa bbbb_new
abcde aaaaa bbbbb_new
insert into your_table
select col1, col2, concat(col3, '_new') from your_table
Consider making a Cartesian Join on your table. This will give you way more data quickly :)
INSERT INTO TABLEDUPLICATES
SELECT * FROM the_table
SELECT * FROM TABLEDUPLICATES UNION
SELECT * FROM the_table
Assuming there is an identity column (ID) you might generate dates (A_Date) like this:
insert into the_table (Column1, Column2, A_Date)
select Column1, Column2, A_Date + (rand(ID) - 0.5) * 100
from the_table
To duplicate rows (all columns) you simply could use
insert into tblname
select * from tblname
to change one column that can be modified to
insert into tblname
select column1, column2, 'fixedvalueforcolumn3' from tblname
But you need a unique value for column 3, so you have to change 'fixedvalueforcolumn3' to a function that will generate some random (unique) value (date in your case) for column 3
insert into tblname
select column1, column2, generateRandomValue() from tblname
Hope that will help you

SQL query to find rows where 1 column value matches another column on another row

I have a database table with a column called 'symbol', that is unique via a non-clustered index.
We now need to change the data in the 'symbol' column, using the data from another column in the same table, say column2.
Trying to do an update, e.g.
update table
set symbol = column2
where column2 <> '' and
deleted = 0
results in a 'Cannot insert duplicate key row in object' error, so there must be 1 or more rows existing in the table that already have a value in the symbol column that is equal to the value in column2, or there are some rows that have a duplicate column 2 value.
I can find the rows that have duplicates in column2, but I'm struggling to come up with a query to find those rows that have a value in the symbol column that exists in any row in column2. Any one got any ideas?
Thanks.
select t1.symbol, count(0) as rows
from table t1
join table t2 on t2.column2 = t1.symbol
group by t1.symbol
Test data:
symbol column2
----------- -----------
1 1
2 1
3 3
4 5
find those rows that have a value in the symbol column that exists in
any row in column2.
select symbol, column2
from table
where symbol in (select column2
from table)
Result:
symbol column2
----------- -----------
1 1
3 3
Or possibly this depending on what result you want.
select symbol, column2
from table as T1
where exists (select *
from table as T2
where T1.symbol = T2.column2 and
T1.symbol <> T2.symbol)
Result:
symbol column2
----------- -----------
1 1

Decomposing a GROUP BY statement

Assuming I have a table SomeTable with the following data:
Primary Key Column1 Column2 Column3 Column4 Column5 Num
1 dat1 abc1 dat3 dat4 por7 1
2 dat1 gcd4 dat3 dat4 yrt8 6
3 dat1 iut7 dat3 dat4 asd6 2
4 other1 other2 other3 other4 other5 4
Another table SomeTableGrouped with a "Group Byed" version created using a query like this:
INSERT INTO SomeTableGrouped
SELECT Column1, Column3, Column4, SUM(Num)
FROM SomeTable
GROUP BY Column1, Column3, Column4
Primary Key Column1 Column3 Column4 Num
100 dat1 dat3 dat4 9
200 other1 other3 other4 4
What I'd like to be able to do is, if I have a primary key of SomeTableGrouped, I need to be able to tell which specific rows from SomeTable it came from.
Example:
In a separate table RandomTable, I have data like this:
Primary Key Column1 SomeTableGroupedId
1 dat1 100
2 dat2 100
If I look at the first row, I need to be able to list out row 1 - 3 from SomeTable
How can I do this? I can't change the schema very much (ie. I can only add new columns, remove columns, add a new table) so a dirty solution is perfectly fine with me.
I think this is what you want.
SELECT id
FROM SomeTable
INNER JOIN SomeTableGrouped ON
(SomeTable.Column1 = SomeTableGrouped.Column1) AND
(SomeTable.Column2 = SomeTableGrouped.Column2) AND
(SomeTable.Column3 = SomeTableGrouped.Column3)
WHERE SomeTableGrouped.id = ...
You don't even need to create all those tables, you only need SomeTable. But here we go...
If you want to find the IDs of the records that summed up, just relate them as they were created:
select st.PrimaryKey as STPK, stg.PrimaryKey as STGPK
from SomeTable st
inner join SomeTableGrouped stg
on (st.Column1 = stg.Column1 and
st.Column3 = stg.Column3 and
st.Column5 = stg.Column5)
However, you should not even have created SomeTableGroupedas a table. It could be a view (look here to see how create views in DB2).
That way, you make sure data is always up-to-date and you don't have to worry about back tracking ("what if Num gets updated?").