Here is table named commonprofit:
name date turnover
1 2011/12 42359
1 2010/12 32863
1 2009/12 24293
1 2008/12 16436
1 2007/12 15442
2 2011/12 91634
2 2010/12 58410
2 2009/12 50668
2 2008/12 54297
3 2009/12 12352
3 2008/12 12352
3 2007/12 14226
select name,max(date) as date, turnover from commonprofit group by name
union
select name,min(date) as date,turnover from commonprofit group by name;
The reslut is
name|date|turnover
00001|2007/12|15442
00001|2011/12|42359
00002|2008/12|54297
00002|2011/12|91634
00003|2007/12|14226
00003|2009/12|12352
Why the result is not the following:
name|date|turnover
00001|2011/12|42359
00002|2011/12|91634
00003|2009/12|12352
00001|2007/12|15442
00002|2008/12|54297
00003|2007/12|14226
I want to know the reason why the sequence is not what i want in the sqlite query?
If you want a specific order you must provide an order by clause. E.g.,
select o, name, date, turnover from
(
select 'x' as o, name, max(date) as date, turnover from commonprofit group by name
union
select 'n' as o, name, min(date) as date, turnover from commonprofit group by name
)
order by o desc, name;
x|1|2011/12|42359
x|2|2011/12|91634
x|3|2009/12|12352
n|1|2007/12|15442
n|2|2008/12|54297
n|3|2007/12|14226
The reason is that UNION removes records that are duplicated in its subqueries.
To make finding duplicates easier, SQLite sorts the result.
To avoid this step, use UNION ALL instead of UNION.
(This implies that if there is a name with only one date, it will appear twice.)
Related
I need to get the next row from an ORDERBY query
I have 2 columns, ID(Primary key), Age(float) in a table T and I need something like the following
SELECT ID FROM T WHERE !> (inputted ID) + 1 rowID/Next row <! ORDERBY Age (then primary key, but I suspect if the Age values are the same SQLite would default to order by primary key anyway) LIMIT 1
Essentially it would select the next row after the inputted ID in the ordered table, its the next row / rowID + 1 I am not sure how to get.
As suggested here is a data set as an example
https://dbfiddle.uk?rdbms=sqlite_3.27&fiddle=19685ac20cc42041a59d318a01a2010f
ID Age
1 12.2
2 36.8
3 22.5
4 41
5 16.7
I am attempting to get the the following row from the ordered (by age) list given a specific ID
ID Age
1 12.2
5 16.7
3 22.5
2 36.8
4 41
Something similar to
SELECT ID FROM OrderedInfo WHERE ID = 5 ORDER BY Age ASC LIMIT 1 OFFSET 1;
My expected result would be '3' from the example data above
I have expanded the data set to include duplicate entries as I didn't implicitly state it could have such data - as such forpas answer works for the first example with no duplicate entries - thanks for your help
https://dbfiddle.uk?rdbms=sqlite_3.27&fiddle=f13d7f5a44ba414784547d9bbdf4997e
Use a subquery for the ID that you want in the WHERE clause:
SELECT *
FROM OrderedInfo
WHERE Age > (SELECT Age FROM OrderedInfo WHERE ID = 5)
ORDER BY Age LIMIT 1;
See the demo.
If there are duplicate values in the column Age use a CTE that returns the row that you want and join it to the table so that you expand the conditions:
WITH cte AS (SELECT ID, Age FROM OrderedInfo WHERE ID = 5)
SELECT o.*
FROM OrderedInfo o INNER JOIN cte c
ON o.Age > c.Age OR (o.Age = c.Age AND o.ID > c.ID)
ORDER BY o.Age, o.ID LIMIT 1;
See the demo.
I will make this question as more precise
I have this data
id product count
1 a 10
1 b 20
1 c 10
1 d 30
I want the result like
Since both product A and B has values i want to count them as one so the result should count(distinct A,C,D) that is 3
If any of product that is (A has values but B does not or vice versa ) then also the result has to be 3
in case both product A and B does not have value then the result should be 2
how to achieve this by using a case statement in oracle plsql
I'm not sure how you define either count of a or either count of b not both, but if you defined it explicitly then you can try this one:
with t as (
select 1 as id, 'a' as product from dual
union all
select 1 as id, 'b' as product from dual
union all
select 1 as id, 'c' as product from dual
union all
select 1 as id, 'd' as product from dual
) select id,
product,
count( case when product in ('c', 'd', 'a') then 1 end ) --change 'a' to 'b' to get the the result for 'b'
from t
group by id, product;
So, I have this table:
id|otherid|key|value
--------------------
1 1 ak av
2 1 bk bv
3 2 ak av
3 2 ak av2
The things to note is that other ids are repeating and they can have same keys with values multiple times. The thing I want to retrieve would be the value for the key, or, if there are multiple values for same key some string.
So, I'd like to receive for otherids
otherid|key|value
-----------------
1 ak av
1 bk bv
2 ak SEQUENCE
Where 'SEQUENCE' string allows me to know that there are multiple values for the single key for otherid. What query would accomplish this?
To get one output row for multiple input rows, use grouping.
The count of rows in the group is available with COUNT(*); you can handle the cases with a CASE expression:
SELECT otherid,
key,
CASE COUNT(*)
WHEN 1 THEN MIN(value)
ELSE 'SEQUENCE'
END AS value
FROM MyTable
GROUP BY otherid,
key;
SELECT DISTINCT
otherid,key,
(SELECT
CASE
WHEN COUNT(value)=1 THEN value
WHEN COUNT(value)=0 THEN '*nil*'
ELSE '*sequence*'
END)
FROM datasingle
WHERE otherid=myid GROUP BY key;
I have gone through a similar post in Stack overflow...
but my query is :
If my table generates a flag in run time execution,then how can I increase Grp_number(generate run time) every time my flag changes.
my Oracle query:
Select emp_id,
Case when MOD(rownum/3)=1 and rownum>1 then 'Y' else 'N' as flag
from Transaction_table
Desired o/p Data format:
emp_id Flag GRP_number
1 N 1
2 N 1
3 N 1
4 Y 2
5 N 2
6 N 2
7 Y 3
You cannot reference a column in another column in the same select list. You need to use sub query to avoid INVALID IDENTIFIER error.
Do it like -
WITH DATA AS(
SELECT emp_id,
CASE
WHEN MOD(rownum/3)=1
AND rownum >1
THEN 'Y'
ELSE 'N' AS flag
FROM Transaction_table
)
SELECT emp_id, flag, SUM(gap) over (PARTITION BY person
ORDER BY DAY) grp
FROM(
SELECT emp_id, flag,
CASE WHEN flag = lag(flag) over (PARTITION BY person
ORDER BY DAY)
THEN 0
ELSE 1
END gap
FROM DATA)
I have a query in Teradata. I want to add an additional column that would be a VARCHAR.
It should say whether the selected record is even or odd
select id, name, CASE newColumn WHEN --- ???
from my table
Like this
id name newColumn
1 asdf odd
2 ts df even
32 htssdf odd
4 asdfsd even
23 gftht odd
How can I do this
Based on your example, I can't tell how you are sorting the results. You would need to define a sort order. Let's assume you would do it based on the id number.
SELECT id, name,
ROW_NUMBER() OVER(ORDER BY id) row_id,
CASE WHEN ROW_NUMBER() OVER(ORDER BY id) MOD 2 = 0 THEN 'Even' ELSE 'Odd' END newColumn
FROM my table
The row_id is incrementally assigned based on the id field being sorted ascending. You then use the MOD function to determine if there's a remainder after dividing the number by a value (in this case 2). Result would look like the following:
id name row_id newColumn
1 asdf 1 Odd
2 ts df 2 Even
4 asdfsd 3 Odd
23 gftht 4 Even
32 htssdf 5 Odd