Postgres Aggregator which checks for occurrences - sql

Does there exist a Postgres Aggregator such that, when used on the following table:
id | value
----+-----------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 3
6 | 3
7 | 3
8 | 4
9 | 4
10 | 5
in a query such as:
select agg_function(4,value) from mytable where id>5
will return
agg_function
--------------
t
(a boolean true result) because a row or rows with value=4 were selected?
In other words, one argument specifies the value you are looking for, the other argument takes the column specifier, and it returns true if the column value was equal to the specified value for one or more rows?
I have successfully created an aggregate to do just that, but I'm wondering if I have just re-created the wheel...

select sum(case when value = 4 then 1 else 0 end) > 0
from mytable
where id > 5

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

Double Join to get data from a table based on other two tables

I have three tables with the following key fields:
CONTRACTS
reference
package
EVENTS
reference
condition1
condition2
TRADES
reference
event_reference
Basically, what I would like to do is the following:
Get all the reference of the table EVENTS where the two conditions (condition1 and condition2) are met;
Hence, getting all the reference of the table TRADES where TRADES.event_reference = EVENTS.reference
Finally, getting the CONTRACTS.package where the CONTRACTS.reference = TRADES.reference (after having filtered the data at the point 2).
In order to do this, I have tried a JOIN statement:
SELECT CONTRACTS.package
FROM CONTRACTS
JOIN TRADES ON CONTRACTS.reference = TRADES.reference
JOIN EVENTS ON TRADES.event_reference = EVENTS.reference
WHERE EVENTS.condition1 = '1.511' AND EVENTS.condition2 IN (1,2)
However, the above (which is executed without errors) does not issue any result, and I would actually expect to see some.
I hence understand that I'm being wrong in the logic that I follow: could anyone please help?
EDIT: this is an example of how the data look like (in yellow, I have highlighted the data that would be touched in the query if it was working as I had it in mind:
...here is the expected result:
1 (package of 4, related to 11 which satisfies condition 1 and 2)
2 (package of 6, related to 13 which satisfies condition 1 and 2)
4 (package of 10, related to 16 which satisfies condition 1 and 2)
and here are the data to copy-paste them:
CONTRACTS
reference package
1 1
2 1
3 1
4 1
5 2
6 2
7 3
8 3
9 4
10 4
EVENTS
reference condition1 condition2
10 1.511 0
11 1.511 1
12 1.202 0
13 1.511 2
14 1.511 0
15 1.202 0
16 1.511 1
TRADES
reference event_reference
2 10
4 11
5 12
6 13
7 14
9 15
10 16
Your query looks OK
SQL Fiddle Demo
SELECT CONTRACTS.package
FROM CONTRACTS
JOIN TRADES ON CONTRACTS.reference = TRADES.reference
JOIN EVENTS ON TRADES.event_reference = EVENTS.reference
WHERE EVENTS.condition1 = 'true' AND EVENTS.condition2 = 'true'
OUTPUT
| package |
|---------|
| 1 |
| 2 |
| 4 |

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.

Returning all children with a recursive select

Good day everyone! I've got a graph. First, I know how to build simple recursive selections. I read some info on msdn.
In this image you can see that (for example) the top node of the graph, which is numbered 0, influences node number 1 (etc (2->4), (3->4), (4->5), (5->6), (1->5))
TASK: for every node show nodes which it influences. For example,
number 1 influences 5 and 6.
The result SQL must return something like this:
who_acts| on_whom_influence
0 | 1
0 | 5
0 | 6
1 | 5
1 | 6
2 | 4
2 | 5
2 | 6
3 | 4
3 | 5
3 | 6
4 | 5
4 | 6
5 | 6
Starting data that I can get using anchor member of CTE are:
who_acts| on_whom_influence
2 | 4
3 | 4
4 | 5
5 | 6
1 | 5
0 | 1
Can I make this selection using SQL syntax and a recursive select? How can I do it?
That sounds like a straightforward CTE. You can pass along the root of the influence in a separate column:
; with Influence as
(
select who_acts
, on_whom_influence
, who_acts as root
from dbo.YourTable
union all
select child.who_acts
, child.on_whom_influence
, parent.root
from Influence parent
join dbo.YourTable child
on parent.on_whom_influence = child.who_acts
)
select root
, on_whom_influence
from Influence
order by
root
, on_whom_influence
Example on SQL Fiddle.