Postgres Query to compare fields and fetch data accordingly - sql

Need help to create query to compare the data and fetch relevant data from table:
Input
Field1
Field2
abc_ID
ID
abc
abc
abc_id_test
test
abc_id_test
abc test
abc_id_test_scenario
scenario
abc_id_test_scenario
cde test
Output
Field1
Field2
abc_id_test_scenario
cde test
If field 2 contains string that matches with field 1 then I need to filter those records.

You can do it using unnest and string_to_array combined to expand a string to a set of rows. then check rows from Field2 not match Field1
with cte as (
select Field1, Field2, unnest(string_to_array(Field2, ' ')) as item
from mytable
)
select field1, Field2
from cte
where Field1 not like concat('%',item,'%')
Demo here

Related

Oracle query to select distinct Value based on another column value

Consider the below sample table:
ID Value
123 ABC
456 DEF
456 ABC
I want the select query result as below:
ID Value
123 ABC
456 DEF
Note: ID has only 2 different values - "123" and "456". Selection should be based on Column "ID". If value "123" is present, the corresponding data from "Value" column has to be selected. If not "456" ID should be retrieved.
simple group by will help you to get the desired result
select min(id), value
from table
group by value
Some thing like this:
select min(id) as id,
Value
from table
group by Value, id
You can use the below if ID is a string like 456 is 'xxx' and 123 is 'yyy' The SQL fiddle here
WITH tt1
AS (SELECT Decode(id, '123', 1,
2) order1,
id,
value1
FROM tt),
tt2
AS (SELECT Min(order1) order1,
value1
FROM tt1
GROUP BY value1)
SELECT tt1.id,
tt1.value1
FROM tt2,
tt1
WHERE tt1.value1 = tt2.value1
AND tt1.order1 = tt2.order1;

Concatenating multiple values into a single string as a subquery without using a variable

I have two row values from table C:
Select Name FROM Table C Where AccountID = 123
COL1
Row 1 |Ricky|
Row 2 |Roxy |
I want to be able to select both of these two values in a SubQuery that will be used in a larger query. So that it displays "Ricky, Roxy"
How can this be done without declaring a variable?
SELECT COL1 = STUFF ((SELECT ',' + COL1 FROM tableC WHERE AccountID=123
FOR XML PATH(''), Type).value('.[1]','nvarchar(max)'),
1,1,'')
This will return all account 123 COL1 values as one column, with commas separating values.
Here is a SQL Fiddle

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

sql query to artificially create rows

I have a piece of code that runs on a variety of databases. It simply runs a configurable sql query which returns a number of rows. From each row, i pull some text and a number to create a new object. Our latest client has decided to put all the text number combinations in a single row of the database i.e
text_1, num_1, text_2, num_2, text_3, num_3
Is there a clever way I can query this to return
text_1,num_1
text_2,num_2
text_3,num_3
so that I don't have to re-code the section for this client.
EDIT:
(Different databases means different RDBMS)
(the commas delimit different columns within a table)
SELECT
CASE row.id WHEN 1 THEN field1
WHEN 2 THEN field3
ELSE field5
END AS new_field_1,
CASE row.id WHEN 1 THEN field2
WHEN 2 THEN field4
ELSE field6
END AS new_field_2
FROM
myTable
CROSS JOIN
(SELECT 1 AS id UNION ALL SELECT 2 UNION ALL SELECT 3) AS row
This should work for most, though still need a little modification (Such as adding 'FROM dual' in the UNIONs for Oracle...)
Alternatively, just UNION three queries together...
SELECT field1, field2 FROM myTable
UNION ALL
SELECT field3, field4 FROM myTable
UNION ALL
SELECT field5, field6 FROM myTable
You can create a function/SP to return a ResultSet the way you need.

SQL: How to append IDs to the rows with duplicate values

I have a table with some duplicate rows. I want to modify only the duplicate rows as follows.
Before:
id col1
------------
1 vvvv
2 vvvv
3 vvvv
After:
id col1
------------
1 vvvv
2 vvvv-2
3 vvvv-3
Col1 is appended with a hyphen and the value of id column.
This SQL will only update duplicates, but not the one with the lowest id :
update tbl
set col1 = col1 + '-' + convert(varchar, id)
where exists(select * from tbl t where t.col1 = tbl.col1 and t.id < tbl.id)
Check IN out in Oracle Syntax. The query is not tested
update table1 set
col1 = col1 || id
where
id not in (
select min(id) from table1
groupby col1
)
You might be able to do that with a sproc and cursors. I don't think it's possible in any reasonable select query.
You can accomplish this with a 2 step process, although an SQL wizard could probably modify this to give you a solution in one step.
First you need to get all the duplicate values. Here is an SQL query that will do that:
SELECT COUNT(*) AS NumberOfDuplicates, col1
FROM Table1
GROUP BY col1
HAVING (COUNT(*) > 1)
This will give you a resultset listing the number of duplicates and the duplicate value.
In step 2 you would loop through this resultset, fetch the col1 value, return all the records containing that value and (possibly using a loop counter variable) alter the value as per your example.
Note: you don't really need to return the number of duplicates to achieve your goal, but it will help you to test the query and be satisfied that it works.