In MySql how do I get row duplication for the case where I pass duplicate IDs in a list? - sql

For this MySQL SELECT statement:
SELECT * FROM MY_TABLE WHERE ID IN(x,y,y,z):
I want 4 rows back - ie I WANT row duplication for the case where I pass duplicate IDs in the list.
Is this possible?

using the IN() construct, that's not possible.
the only way i can think to do this is with a UNION:
SELECT * FROM my_table WHERE id = x
UNION ALL
SELECT * FROM my_table WHERE id = y
UNION ALL
SELECT * FROM my_table WHERE id = y
UNION ALL
SELECT * FROM my_table WHERE id = z
but in all honesty, i would just do the IN() like you have it and make your app code duplicate the rows as needed.

Put your IDs, including dups in a temp table and join your results on that table. The join will take care of filtering, but will keep duplicates if it's in the temp table twice

SELECT * FROM MY_TABLE WHERE ID IN(x,y,z)
union all
SELECT * FROM MY_TABLE WHERE ID IN(y)

To me, IN specify a set of values to search in (and duplication is a concept that conflict with the set one).
You should use other mean to reach your scope.

Related

2 Queries to do the same thing not working

I have 2 queries. The first is what I want to accomplish, however, it was taking much too long. Here's how the query looked like:
SELECT *
FROM old_table
WHERE id NOT IN (SELECT id FROM new_table)
UNION ALL
SELECT *
FROM new_table
Basically, I want everything that's in the old table, but not in the new table. I then union everything from the old and new. Again, this query was taking much too long on a bigger dataset. So, I optimized it like so:
WITH union_tbl AS (
(SELECT * FROM old_table)
UNION ALL
(SELECT * FROM new_table)
), row_tbl AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY ordering) AS row
FROM union_tbl
)
SELECT *
FROM row_tbl
WHERE row = 1
In the old_table and new_table (in a separate query) I add a new column to each called ordering. The new_table gets 1 for all its rows. For the old table, it gets 2 for all its rows. In the end, I select where the row number is 1. So that means if there's 2 rows one for new_table and one for old_table then it should get the new_table row instead.
This is how I'm envisioning it, however, I'm not getting the same results as my previous query. I'd expect it to have the same exact results with the same rows. What am I getting wrong? Is my query logic incorrect?
Can you try the below code?
SELECT a.*
FROM old_table a left join new_table b on a.id=b.id
WHERE b.id IS NULL
UNION ALL
SELECT *
FROM new_table
This is a very optimized way

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

How to add union data in table?

Thanks in advance !!
I want to get below data in separate table with column how can we achieved this.
From my reading of your question, you would like the results of that SELECT statement put into a new table?
Firstly, I'm assuming your original SQL works as a SELECT statement - e.g., all those tables have the same structure. Note that you can simplify the unions, but I haven't done so here, to keep the key part of the answer (saving the data) as the main focus.
To save the data into another table, you can either create a table first and make that into an insert, or just use 'SELECT INTO' within the main SELECT.
If you are happy with the columns being automatically created, the 'SELECT INTO' version will create columns (e.g., you do not need to specify the columns in a CREATE TABLE statement). However, when you run the SELECT INTO, it does create the table. Therefore if you want to insert further values, you need to specify the column list (or have matching column lists).
SELECT INTO version
select *
INTO #Temp -- Added This row
from
( select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
) A
except
select * from
( select * from #ONEYRCON
union all
select * from #OTHERYRCON
) B
INSERT INTO version
CREATE TABLE #Temp (<your fields here to match the SELECT statement>)
INSERT INTO #Temp
select * from
( select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
) A
except
select * from
( select * from #ONEYRCON
union all
select * from #OTHERYRCON
) B
Set operators are evaluated from top to bottom so there only needs to be 1 subquery. Something like this
select ab.* into #Temp
from (select * from #OneyearExpiry
union all
select * from #OtherYearExpiry
except
select * from #ONEYRCON
except
select * from #OTHERYRCON) ab;

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 )

SQL Server: Find Values that don't exist in a table

I have a list or set of values that I would like to know which ones do not currently exist in a table. I know I can find out which ones do exist with:
SELECT * FROM Table WHERE column1 IN (x,x,x,x,x)
The set is the values I am checking against. Is there a way to find out which values in that set do not exist in column1? Basically, I'm looking for the inverse of the sql statement above.
This is for a report, so all I need is the values that don't exist to be returned back.
I have and could do this with a left join and putting the values in another table, but the values I check are always different and was hoping to find a solution that didn't involve clearing a table and inserting data first. Trying to find a better solution for me if one exists.
You can also use EXCEPT as well as the OUTER JOIN e.g.
SELECT * FROM
(
SELECT -1 AS N
UNION
SELECT 2 AS N
) demo
EXCEPT
SELECT number
FROM spt_values
WITH q(x) AS
(
SELECT x1
UNION ALL
SELECT x2
UNION ALL
SELECT x3
)
SELECT x
FROM q
WHERE x NOT IN
(
SELECT column1
FROM [table]
)
Put the values you want to check for in a table A
LEFT OUTER JOIN the table A against your Table WHERE Table.column1 IS NULL
SELECT column1
FROM A
LEFT OUTER JOIN
Table
ON A.column1 = Table.column1
WHERE Table.column1 IS NULL
This will only show the rows that exist in A but not in Table.
As you want some of the values from the set in the result, and you can't take them from the table (as you want the ones that doesn't exist there), you have to put the set in some kind of table or result so that you can use that as source.
You can for example make a temporary result, that you can join against the table to filter out the ones that does exist in the table:
select set.x
from (
select 1 as x union all
select 2 union all
select 3 union all
select 4 union all
select 5
) as set
left join Table as t on t.column1 = set.x
where t.columnn1 is null
One way you can do it is:
SELECT * FROM Table WHERE column1 NOT IN(...);
Use the NOT operator:
SELECT * FROM Table WHERE column1 NOT IN (x,x,x,x,x)