Select a row of the table with desired value, when a column's value which is not in the table is selected in where clause in keyword? - sql

I have a table with one of the columns as ID. I have a set of values which I give in the where clause to compare the 'ID' column using 'in' keyword. I want to select the row if the value in that set of values has a record in the table. If not, the value that is not in the table has to be selected along with empty values other columns.
For example:
There is a table with columns ID & Animal. It has 8 records.
The table with all records
If I run the query:
SELECT ID, Animal from #Temp1 where ID in (4,8)
it will return the following result.
The table result filtered
But, if I run the query:
SELECT ID, Animal from #Temp1 where ID in (4,8,12)
it should return the following result.
The table result with desired values

Use a LEFT JOIN in concert with string_split() instead
Select ID = A.value
,Animal = coalesce(B.Animal,'ID Not Found')
From string_split('4,8,12',',') A
Left Join YourTable B on A.value=B.ID
Results
ID Animal
4 Donkey
8 Hampster
12 ID Not Found
If by chance string_split() is not available
Select ID = A.value
,Animal = coalesce(B.Animal,'ID Not Found')
From (values (4)
,(8)
,(12)
) A(value)
Left Join YourTable B on A.value=B.ID

Related

What is the SQL standard for updating one row when multiple are matched with an UPDATE+FROM

With the following SQL:
CREATE TABLE tableA (
id int primary key,
local_id int not null
);
INSERT INTO tableA (id,local_id) VALUES
(122,0),(123,0),(124,0);
UPDATE tableA SET tableA.local_id = tableB.id
FROM (
SELECT 1 AS id, 1 AS rn
UNION
SELECT 3 AS id, 1 AS rn
UNION
SELECT 2 AS id, 1 AS rn
) AS tableB
WHERE tableA.id = 123 AND tableB.rn = 1;
This SQL matches only 1 row in tableA and 3 rows in tableB.
What is the rule for updating local_id in this case? without an ORDER BY inside the inner FROM, it seems that it picks the highest INT, but I doubt that behavior is explicit? (In this case it is 3).
Is this behavior defined somewhere in the SQL standard?
If I set ORDER BY id DESC inside the parenthesis, am I certain it will always pick the top row?
This is a simplified problem, usually, more than 1 row is updated in tableA, so setting a TOP/LIMIT is not going to cut it.
Current query give just an error. You can update multiple rows with 1 value from target table. But you can't update 1 row with multiple values from target. So just make target table unique. As you mentioned, get max value.

How to select only values that are not repeating in a column example if a have column with following values "A,b,c,a,c" i have to select only b

How to select only values that are not repeating in a column? For example if a have table with following values I expect to return only the id value of b:
id
--
a
b
c
a
c
Aggregation provides one approach:
SELECT id
FROM yourTable
GROUP BY id
HAVING COUNT(*) = 1;
In subselecet you select values which have only one record, Than in outer select you search for all datas based on that value in subselect
SELECT *
FROM table
WHERE id IN (SELECT id
FROM table
GROUP BY id
HAVING COUNT (id) = 1)

Get rows in sequence from multiple table in SQL Server

I want to get all rows in sequence from 2 tables in SQL Server.
Output should be 1st row from 1st table, then 1st row from 2nd table,
2nd row from 1st table, 2nd row from 2nd table....etc
What #eshirvana suggested will not get you the desired. Instead, it'll be table1.row1, table2.row1, table2.row2, table1.row2
You can use UNION to join data from two tables when the column names and types match. I'm making an assumption on how to order the data based on your desired outcome.
SELECT RowID, Row, z
FROM table1
UNION
SELECT *
FROM table2
ORDER BY z, RowID
Here's the working code:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=068c0fd2056cc48718345e85b74b7bba
probably something like that :
select * from
(
select rowID,Row,z from table1
union all
select rowID,Row,z from table2
) alltables
order by z
You can try with below approach:
SELECT * FROM
(
SELECT RowId,Row,Z,1 AS TableOrder From Table1
UNION ALL
SELECT RowId,Row,z,2 AS TableOrder From Table2
)
ORDER BY Z,TableOrder

Select rows where one column has duplicate values based on another column which contains specific strings

I have a table where in customer number column contains duplicate values and I would like to select all rows where there are duplicate entries for customer number, but only select those rows where WO Type column only contains these specific values ('IMU','Electric') so in the table image attached to this question: I should only get rows for ID 1 and 2.
I do not want those duplicates counted where the pair of duplicate rows also contain GAS, but only want those duplicate rows which exclusively contain only IMU and Electric values in WO Type Column
Your help is much appreciated.
You can use group by and having:
select customerNumber
from t
where woType in ('EMU', 'Electric')
group by customerNumber
having count(*) = 2;
Note: This assumes no duplicates. To handle this, you can use:
having min(woType) <> max(woType)
or:
having count(distinct woType) = 2 -- number of elements in IN list
SELECT *
FROM tbl t1
WHERE EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'IMU'
) AND EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype = 'Electric'
) AND NOT EXISTS
(
SELECT * FROM tbl t2
WHERE t2.customernumber = t1.customernumber
AND t2.wotype NOT IN ('IMU', 'Electric')
)
Here's a fiddle.
Try this:
select * from Table1 Main
Inner JOIN (
select Customer_Number
From Table1
group by Customer_Number
Having COunt(Customer_Number)>1) SUB ON Main.Customer_Number=SUB.Customer_Number
WHERE Main.Wo_Type IN ('IMU','Electric')
This Query will return the duplicate set or rows in the table.

Oracle: extract data from MDSYS.SDO_GEOMETRY column

I have a table form which I need to extract some information. This table has an oracle spatial (MDSYS.SDO_GEOMETRY) column, from which I also need some data.
I started out with a simple query like this:
select id, field1, field2
FROM my_table;
After that, I was able to loop over the result to extract the data that was in the spatial column:
SELECT *
FROM TABLE (SELECT a.POSITIONMAP.sdo_ordinates
FROM my_table
WHERE ID = 18742084);
The POSITIONMAP.sdo_ordinates seems to usually hold 4 values, like these:
100050,887
407294,948
0,577464740471056
-0,816415625470689
I need the last 2 values. I can achieve that by changing the query into this:
SELECT * FROM
(SELECT rownum AS num,
column_value AS orientatie
FROM TABLE (SELECT a.POSITIONMAP.sdo_ordinates
FROM my_table
WHERE ID = 18742084))
WHERE num IN (3,4)
Looping over every row from my first query to extract the data from the POSITIONMAP column is of course not very performance friendly, so my query becomes slow very quickly.
I would like to retrieve all information in one query, but there are a few things that prevent me from doing so.
Not every row in the table has data in POSITIONMAP
Some rows do have data in POSITIONMAP, but they only contain 2 values (so not the 3rd and 4th value that I am looking for.
I need the data in one row for every row in the table (using the previous query would result in duplicate rows
The closest I got is:
select
id,
field1,
field2
t.*
FROM my_table v,
table (v.POSITIONMAP.sdo_ordinates) t
This gives my 4 rows for every row in my_table.
As soon as I try to put the rownum condition into this query, I get an error: "invalid user.table.column, table.column, or column specification"
Is there any way to combine what I want to do into 1 query?
You can use sdo_util.getvertices as follows:
select t.x,t.y
from my_table mt
,table(sdo_util.getvertices(mt.positionmap)) t
where t.id = 2
I'm assuming that your geometries are lines (gtype=2002) and points (gtype= 2001). If you want X,Y values for lines and empty values for point you can filter on the sdo_gtype property of the geometry object.
select t.x,t.y
from my_table mt
,table(sdo_util.getvertices(mt.positionmap)) t
where t.id = 2
and mt.positionmap.sdo_gtype=2002
union all
select null as X,
null as Y
from my_table mt
where mt.positionmap.sdo_gtype=2001
One method is to use the ROW_NUMBER() analytic function:
SELECT *
FROM (
select id,
field1,
field2,
t.*,
ROW_NUMBER() OVER ( PARTITION BY v.id ORDER BY ROWNUM ) AS rn
FROM my_table v,
TABLE( v.POSITIONMAP.sdo_ordinates ) t
)
WHERE rn IN ( 3, 4 )