reorder sort_order in table with sqlite - sql

I have this table:
id sort_ord
0 6
1 7
2 2
3 3
4 4
5 5
6 8
Why does this query:
UPDATE table
SET sort_ord=(
SELECT count(*)
FROM table AS pq
WHERE sort_ord<table.sort_ord
ORDER BY sort_ord
)
WHERE(sort_ord>=0)
Produce:
id sort_ord
0 4
1 5
2 0
3 1
4 2
5 4
6 6
I was expecting all sort_ord fields to subtract by 2.

Here is defined: https://www.sqlite.org/isolation.html
About this link i can interpret, you has several instances for one query (update table and select count table) and independent of each other.
When you are in update sort_data(5) id 5, you have new data for read on every "SET sot_ord" (understanding what say about isolation), and now the result is 4.
Every select is a new instance and a new data reading
id sort_ord
0 4
1 5
2 0
3 1
4 2
5 5**
6 8**

Related

How to merge two rows if same values in sql server

I have the Following Output:
Sno
Value Stream
Duration
Inspection
1
Test1
3
1
2
ON
14
0
3
Start
5
0
4
Test1
5
1
5
OFF
0
1
6
Start
0
1
7
Test2
0
1
8
ON
3
1
9
START
0
1
10
Test2
2
2
I want to merge the same value after that before START values charge to after ON. For example S.no 4 will merge to s.no4.
1 | Test1 | 8 | 2 |
If the combination is not equal then don't allow it to merge. For Example, we have to consider only On/Start. If the condition is OFF/Start then don't allow to merge. E.g. S.no 5 and 6 OFF/Start then don't allow to merge s.no 4 & 7.
I think you are talking about summarization not merging:
select [Value Stream],
min(Sno) as First_Sno,
sum(Duration) as total_Duration,
sum(Inspection) as Inspection
from yourtable
group by [Value Stream]
Will give you the result

SQL update by groups?

I'd like to update approximately the first X number of rows in a table but I want to always update all rows with a matching column at the same time. So if my table has:
MyID Transaction Amount Date Status
1 1 2 02/08/2016 0
1 1 4 02/08/2016 0
2 4 1 02/08/2016 0
2 3 2 02/08/2016 0
3 10 1 02/08/2016 0
3 6 4 02/08/2016 0
I want to update Status to 1 on approximately the first 5 rows, but I don't want to split up matching MyID values, how can I do that? I could update the first 4 or 6 in this example.
Here is one method:
update t
set status = 1
where myId in (select top 5 MyId from t order by MyId);

Using temporary extended table to make a sum

From a given table I want to be able to sum values having the same number (should be easy, right?)
Problem: A given value can be assigned from 2 to n consecutive numbers.
For some reasons this information is stored in a single row describing the value, the starting number and the ending number as below.
TABLE A
id | starting_number | ending_number | value
----+-----------------+---------------+-------
1 2 5 8
2 0 3 5
3 4 6 6
4 7 8 10
For instance the first row means:
value '8' is assigned to numbers: 2, 3 and 4 (5 is excluded)
So, I would like the following intermediairy result table
TABLE B
id | number | value
----+--------+-------
1 2 8
1 3 8
1 4 8
2 0 5
2 1 5
2 2 5
3 4 6
3 5 6
4 7 10
So I can sum 'value' for elements having identical 'number'
SELECT number, sum(value)
FROM B
GROUP BY number
TABLE C
number | sum(value)
--------+------------
2 13
3 8
4 14
0 5
1 5
5 6
7 10
I don't know how to do this and didn't find any answer on the web (maybe not looking with appropriate key words...)
Any idea?
You can do what you want with generate_series(). So, TableB is basically:
select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA;
Your aggregation is then:
select n, sum(value)
from (select id, generate_series(starting_number, ending_number - 1, 1) as n, value
from tableA
) a
group by n;

MDX: iif condition on the value of dimension

I have 1 Virtual cube consists of 2 cubes.
Example of fact table of 1st cube.
id object_id time_id date_id state
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 0
5 11 4 1 0
6 11 7 1 1
7 10 8 1 0
8 11 5 1 0
9 10 7 1 1
10 10 9 1 2
Where State: 0 - Ok, 1 - Down, 2 - Unknown
For this cube I have one measure StateCount it should count States for each object_id.
Here for example we have such result:
for 10 : 3 times Ok , 2 times Down, 1 time Unknown
for 11 : 3 times Ok , 1 time Down
Second cube looks like this:
id object_id time_id date_id status
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 1
5 11 4 1 1
Where Status: 0 - out, 1 - in. I keep this in StatusDim.
In this table I keep records that should not be count. If object have status 1 that means that I have exclude it from count.
If we intersect these tables and use StateCount we will receive this result:
for 10 : 2 times Ok , 1 times Down, 1 time Unknown
for 11 : 2 times Ok , 1 time Down
As far as i know, i must use calculated member with IIF condition. Currently I'm trying something like this.
WITH MEMBER [Measures].[StateTimeCountDown] AS(
iif(
[StatusDimDown.DowntimeHierarchy].[DowntimeStatus].CurrentMember.MemberValue
<> "in"
, [Measures].[StateTimeCount]
, null )
)
The multidimensional way to do this would be to make attributes from your state and status columns (hopefully with user understandable members, i. e. using "Ok" and not "0"). Then, you can just use a normal count measure on the fact tables, and slice by these attributes. No need for complex calculation definitions.

SQL: Create view from 2 tables printing null values when no records

I have in my DB these 2 tables:
LESSONS RATINGS
ID | NAME ID | LESSON | RATING
1 lesson1 1 1 4
2 lesson2 2 2 2
3 lesson3 3 1 5
4 lesson4 4 4 2
5 lesson5 5 3 1
6 lesson6 6 2 5
7 lesson7 7 6 3
And I want a View that show me something like this:
LESSONS_RATINGS
IDL| NAME | RATING
1 lesson1 4.5
2 lesson2 3.5
3 lesson3 1
4 lesson4 2
5 lesson5 NULL
6 lesson6 3
7 lesson7 NULL
But what I've been able to get so far is this:
LESSONS_RATINGS
IDL| NAME | RATING
1 lesson1 4.5
2 lesson2 3.5
3 lesson3 1
4 lesson4 2
6 lesson6 3
Notice that NULL records are missing. That's why in table RATINGS there are no records of lessons 5 and 7. I'm doing this:
CREATE OR REPLACE VIEW `LESSONS_RATINGS` AS
select
`l`.`ID` AS `IDL`,
`l`.`NAME` AS `NAME`,
CASE WHEN AVG(`lr`.`RATING`) IS NULL THEN NULL ELSE AVG(`lr`.`RATING`) END AS `RATING`
from
`LESSONS` AS `l`,
`RATINGS` AS `lr`
where
(`l`.`ID` = `lr`.`ID`)
group by `l`.`ID`;
Use an OUTER JOIN:
select
`l`.`ID` AS `IDL`,
`l`.`NAME` AS `NAME`,
AVG(`lr`.`RATING`) AS `RATING`
from
`LESSONS` AS `l` LEFT JOIN `RATINGS` AS `lr`
ON `l`.`ID` = `lr`.`ID`
group by `l`.`ID`;
Also, I don't think there is a need for the Case statement -- you can just use AVG(lr.rating).
A Visual Explanation of SQL Joins