I have the following query:
SELECT * from tWords where WordAton IN ("bbb", "aaa2", "ccc", "aaa1")
the query returns first the results for "aaa1" then for "aaa2" then for "bbb" and then for "ccc". Is there a way to return the results in the order of the input array, which means first the results for "bbb" then for "aaa2"... etc.
Thank you in advance.
You can apply conditional ordering like this:
SELECT *
from tWords
where WordAton IN ('bbb', 'aaa2', 'ccc', 'aaa1')
order by case WordAton
when 'bbb' then 1
when 'aaa2' then 2
when 'ccc' then 3
when 'aaa1' then 4
end
In SQL (not just SQLite), the only way to always return rows in a given order is with a SQL ORDER BY ... clause. So the short answer is, "No", there's no simple way to return rows in the order given by the contents of an IN (...) clause.
You could use a common table expression (CTE) to define a sort order, but that's usually not worth the trouble. This isn't the same thing as ordering by the contents of a IN (...) clause, but it looks the same. (You're ordering by the sort order specified in the CTE.)
with ordered_words as (
select 1 as sort_order, 'bbb' as WordAton union
select 2, 'aaa2' union
select 3, 'ccc' union
select 4, 'aaa1'
)
select t.WordAton
from tWords t
join ordered_words o on t.WordAton = o.WordAton
where t.WordAton in ('bbb', 'aaa2', 'ccc', 'aaa1')
order by o.sort_order;
Related
I need to output running balance in the following query, Please help me with the query-code:
select
WEAVING_YARN_TR.TR_ID,
WEAVING_YARN_TR.GP_NO,
WEAVING_YARN_TR.YR_ID,
WEAVING_YARN_GATEPASS.TO_FROM as PARTY,
WEAVING_YARN_GATEPASS.GP_DATE,
WEAVING_YARN_TR.BAGS_IN,
WEAVING_YARN_TR.BAGS_OUT,
SUM(NVL(WEAVING_YARN_TR.BAGS_OUT,0)-NVL(WEAVING_YARN_TR.BAGS_IN,0)) over (order by GP_DATE) as BALANCE
from WEAVING_YARN_TR,WEAVING_YARN_GATEPASS
where WEAVING_YARN_TR.GP_NO=WEAVING_YARN_GATEPASS."GP_NO." and WEAVING_YARN_TR.YR_ID=:P216_YR_ID and WEAVING_YARN_GATEPASS.TO_FROM=:P216_YR_DESC
UNION ALL
select
null as TR_ID,
WEAVING_WARP_SET.SET_ID,
WEAVING_WARP_SET.YARN_ITEM,
WEAVING_WARP_SET.PARTY,
WEAVING_WARP_SET.RECEIVED_DATE,
WEAVING_WARP_SET.TOTAL_BAGS_CONSUMED,
null as BAGS_OUT,
NVL(null,0)-NVL(WEAVING_WARP_SET.TOTAL_BAGS_CONSUMED,0) as BALANCE
from WEAVING_WARP_SET
where WEAVING_WARP_SET.YARN_ITEM=:P216_YR_ID and WEAVING_WARP_SET.PARTY= :P216_YR_DESC
order by GP_DATE
So here is the thing; if you're going to use UNION or UNION ALL, each query block has to be the equal column and type.
For example; We have 2 queries and we want to bind them.
The first query block contains 3 columns and their type NUMBER, VARCHAR, NUMBER (in order). The second block has to be 3 column and types must be NUMBER, VARCHAR, VARCHAR (in order)
So your query does not seem like that. You want an output like the screenshot that you sent. Here is the query that edited:
select
weaving_yarn_gatepass.gp_date
,weaving_yarn_tr.gp_no
,weaving_yarn_gatepass.to_from as party
,weaving_yarn_tr.yr_id
,weaving_yarn_tr.bags_in
,weaving_yarn_tr.bags_out
,sum(nvl(weaving_yarn_tr.bags_out,0) - nvl(weaving_yarn_tr.bags_in,0)) over(order by gp_date) as balance
from weaving_yarn_tr
,weaving_yarn_gatepass
where weaving_yarn_tr.gp_no = WEAVING_YARN_GATEPASS."GP_NO."
and weaving_yarn_tr.yr_id = :p216_yr_id
and weaving_yarn_gatepass.to_from = :p216_yr_desc
union all
select
weaving_warp_set.received_date --I don't know if it means gp_date
,null as gp_no
,weaving_warp_set.party
,null yr_id -- If there is a column named YR_ID in WEAVING_WARP_SET put here
,weaving_warp_set.total_bags_consumed
,null as bags_out
,nvl(null,0) - nvl(weaving_warp_set.total_bags_consumed,0) as balance
from weaving_warp_set
where weaving_warp_set.yarn_item = :p216_yr_id
and weaving_warp_set.party = :p216_yr_desc
order by gp_date;
I'm performing an Sqlite3 query similar to
SELECT * FROM nodes WHERE name IN ('name1', 'name2', 'name3', ...) LIMIT 1
Am I guaranteed that it will search for name1 first, name2 second, etc? Such that by limiting my output to 1 I know that I found the first hit according to my ordering of items in the IN clause?
Update: with some testing it seems to always return the first hit in the index regardless of the IN order. It's using the order of the index on name. Is there some way to enforce the search order?
The order of the returned rows is not guaranteed to match the order of the items inside the parenthesis after IN.
What you can do is use ORDER BY in your statement with the use of the function INSTR():
SELECT * FROM nodes
WHERE name IN ('name1', 'name2', 'name3')
ORDER BY INSTR(',name1,name2,name3,', ',' || name || ',')
LIMIT 1
This code uses the same list from the IN clause as a string, where the items are in the same order, concatenated and separated by commas, assuming that the items do not contain commas.
This way the results are ordered by their position in the list and then LIMIT 1 will return the 1st of them which is closer to the start of the list.
Another way to achieve the same results is by using a CTE which returns the list along with an Id which serves as the desired ordering of the results, which will be joined to the table:
WITH list(id, item) AS (
SELECT 1, 'name1' UNION ALL
SELECT 2, 'name2' UNION ALL
SELECT 3, 'name3'
)
SELECT n.*
FROM nodes n INNER JOIN list l
ON l.item = n.name
ORDER BY l.id
LIMIT 1
Or:
WITH list(id, item) AS (
SELECT * FROM (VALUES
(1, 'name1'), (2, 'name2'), (3, 'name3')
)
)
SELECT n.*
FROM nodes n INNER JOIN list l
ON l.item = n.name
ORDER BY l.id
LIMIT 1
This way you don't have to repeat the list twice.
I want to sort semicolon separated values per row in a column. Eg.
Input:
abc;pqr;def;mno
xyz;pqr;abc
abc
xyz;jkl
Output:
abc;def;mno;pqr
abc;pqr;xyz
abc
jkl;xyz
Can anyone help?
Perhaps something like this. Breaking it down:
First we need to break up the strings into their component tokens, and then reassemble them, using LISTAGG(), while ordering them alphabetically.
There are many ways to break up a symbol-separated string. Here I demonstrate the use of a hierarchical query. It requires that the input strings be uniquely distinguished from each other. Since the exact same semicolon-separated string may appear more than once, and since there is no info from the OP about any other unique column in the table, I create a unique identifier (using ROW_NUMBER()) in the most deeply nested subquery. Then I run the hierarchical query to break up the inputs and then reassemble them in the outermost SELECT.
with
test_data as (
select 'abc;pqr;def;mno' as str from dual union all
select 'xyz;pqr;abc' from dual union all
select 'abc' from dual union all
select 'xyz;jkl' from dual
)
-- End of test data (not part of the solution!)
-- SQL query begins BELOW THIS LINE.
select str,
listagg(token, ';') within group (order by token) as sorted_str
from (
select rn, str,
regexp_substr(str, '([^;]*)(;|$)', 1, level, null, 1) as token
from (
select str, row_number() over (order by null) as rn
from test_data
)
connect by level <= length(str) - length(replace(str, ';')) + 1
and prior rn = rn
and prior sys_guid() is not null
)
group by rn, str
;
STR SORTED_STR
--------------- ---------------
abc;pqr;def;mno abc;def;mno;pqr
xyz;pqr;abc abc;pqr;xyz
abc abc
xyz;jkl jkl;xyz
4 rows selected.
I am new in oracle and I want to get the value from a column which is stored as "Ashu||123 ||Main Menu|ENG||1|1".
as you can see each value is separated by || symbol.in the above value Ashu is the customer name and 123 is the id, I want both value as customer-name and customer id.
In the query below, I include some test data "on the fly" (not part of the solution; use your actual table name instead of test_data in the main query, and your actual column name instead of str). I included several special cases for testing, to make sure the query works correctly in all cases. I assume the first value (before the first ||) is the customer name and the second the customer id, and the rest of the input string can be ignored. I looked in particular to see that the query handles null values correctly (assuming they may happen in your data).
I left the customer id as a string; if it must be a number, it may be better to wrap it all within to_number().
with
test_data ( str ) as (
select 'Ashu||123||Main Menu|ENG||1|1' from dual union all
select 'Misha||125' from dual union all
select 'Babu||||Main Menu|NZL||?' from dual union all
select 'Rim||' from dual union all
select 'Todd' from dual union all
select '||139||Other Stuff' from dual
)
-- end of test data (only for testing and illustration) - not part of solution
-- SQL query begins BELOW THIS LINE
select str,
regexp_substr(str, '([^|]*)(\|\||$)', 1, 1, null, 1) as cust_name,
regexp_substr(str, '([^|]*)(\|\||$)', 1, 2, null, 1) as cust_id
from test_data
;
STR CUST_NAME CUST_ID
----------------------------- --------- -------
Ashu||123||Main Menu|ENG||1|1 Ashu 123
Misha||125 Misha 125
Babu||||Main Menu|NZL||? Babu
Rim|| Rim
Todd Todd
||139||Other Stuff 139
6 rows selected.
I would like to determine particular IDs that are not present in a table.
For example, I have the IDs 1, 2 and 3 and want to know if they exist in the table.
Essentially this would boil down to:
SELECT id FROM (
SELECT 1 AS id
UNION
SELECT 2 AS id
UNION
SELECT 3 AS id
)
WHERE
NOT EXISTS (SELECT * FROM table WHERE table.id = id)
Suppose table had the IDs 1 and 4, then this would yield 2 and 3.
Are there more elegant / concise / faster ways to get those IDs in SQLite ?
The compound SELECT operator EXCEPT allows you to do something similar to NOT EXISTS:
SELECT 1 AS id UNION ALL
SELECT 2 UNION ALL
SELECT 3
EXCEPT
SELECT id FROM MyTable
Beginning with SQLite 3.8.3, you can use VALUES everywhere you could use SELECT, but this is just a different syntax:
VALUES (1),
(2),
(3)
EXCEPT
SELECT id FROM MyTable