Reputation: 1989
SELECT COLUMN_A, COLUMN_B, COLUMN_C
FROM MY_TABLE
WHERE SOMETHING IN ('10', '20', '30', '40', '50', '60', '10');
Since value '10' is a duplicate, I only get 6 rows of data back, instead of the desired 7 rows of data. I need results back for every value in ('10', '20', '30', '40', '50', '60', '10').
How can I get 2 rows of data back for value '10' instead of just 1 row? Although it may not seem practical, this is exactly what I need done. Any assistance is much appreciated.
Upvotes: 0
Views: 47
Reputation: 41
You can use join for achieving this. First split the comma separated values in IN CLAUSE into table form and use join with your table.
Split function you can use MSDN https://blogs.msdn.microsoft.com/amitjet/2009/12/11/convert-comma-separated-string-to-table-4-different-approaches/ Sample code below: I used the CTE approach to split
DECLARE @PARAMS VARCHAR(50)='10, 20, 30, 40, 50, 60, 10'
;WITH STRCTE(START, STOP) AS
(
SELECT 1, CHARINDEX(',' , @PARAMS )
UNION ALL
SELECT STOP + 1, CHARINDEX(',' ,@PARAMS , STOP + 1)
FROM STRCTE
WHERE STOP > 0
)
SELECT SUBSTRING(@PARAMS , START, CASE WHEN STOP > 0 THEN STOP-START ELSE 4000 END) AS STRINGVALUE INTO #TEMP FROM STRCTE
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE INNER JOIN #TEMP ON SOMETHING = STRINGVALUE
Upvotes: 0
Reputation: 7465
You could do something like this.
The string gets converted to a nested table query and then you join against that.
SELECT *
FROM
(
select
trim(regexp_substr(t.MESSAGES, '[^,]+', 1, levels.column_value)) as SPLIT_MESSAGE
from
(SELECT '10, 20, 30, 40, 50, 60, 10' MESSAGES FROM DUAL) t,
table(cast(multiset(select level from dual connect by level <= length (regexp_replace(t.MESSAGES, '[^,]+')) + 1) as sys.OdciNumberList)) levels
) A
INNER JOIN MY_TABLE ON MY_TABLE.SOMETHING=A.SPLIT_MESSAGE
Upvotes: 1
Reputation: 37472
You could use UNION ALL
like:
SELECT COLUMN_A,
COLUMN_B,
COLUMN_C
FROM MY_TABLE
WHERE SOMETHING IN ('10',
...
'60')
UNION ALL
SELECT COLUMN_A,
COLUMN_B,
COLUMN_C
FROM MY_TABLE
WHERE SOMETHING IN ('10');
Or you could create a temporary table with the filter values and join it:
CREATE GLOBAL TEMPORARY TABLE SOMETHINGS
AS
SELECT '10' SOMETHING
FROM DUAL
UNION ALL
...
UNION ALL
SELECT '10' SOMETHING
FROM DUAL;
SELECT COLUMN_A,
COLUMN_B,
COLUMN_C
FROM MY_TABLE
INNER JOIN SOMETHINGS
ON SOMETHINGS.SOMETHING = MY_TABLE.SOMETHING;
DROP TABLE SOMETHINGS;
Upvotes: 1
Reputation: 48769
You can use UNION ALL
to consolidate multiple queries.
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '10'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '20'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '30'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '40'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '50'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '60'
union all
SELECT COLUMN_A, COLUMN_B, COLUMN_C FROM MY_TABLE WHERE SOMETHING = '10'
In any case, it's unclear to me why you need this. Besides, it's not very efficient in terms of database load and performance, even if you have an index on SOMETHING
.
Upvotes: 1