Deterministic Finite Automata on JFLAP - finite-automata

I have a DFA problem and I need to use JFLAP to create a diagram for the automata. I have successfully done a more simple problem, however I just can't figure out how to solve this one:
"A DFA that receives sequences of "1" and "2" values, accepting only sequences that result in 4. Any other combinations that result in more than or less than 4 are to be rejected."
The alphabet is {1,2} and as far as I know these are the possible combinations that will be accepted:
1111, 22, 121, 112, 211
Any help will be very much appreciated. Thank you.

A DFA for this finite language could look a lot like this:
1 1 1 1
----->q----->q1----->q11----->q111----->q1111
| | | | |
| 2 | 2 | 1 | 2 | 1,2
| | | | |
V 1 V 1 V | |
q2----->q21----->q211 | |
| | | | |
| 2 | 2 | 1,2 | |
| | | | |
V | | | |
q22 | | | |
| | | | |
| 1,2 | | | | +-----+
| | | | | | | 1,2
V V V V V V |
+-------+--------+------+---------+--------->qDead----+
Another approach would be just to remember the current sum:
1
----->q0----->q1
| /|
| / |
| / |
2 | 1 / | 2
| / |
| / |
| / |
|/ |
V 1 V
q2----->q3
| /|
| / |
| / |
2 | 1 / | 2
| / |
| / |
| / |
|/ |
V 1,2 V
q4----->qDead

Related

Is there a way using PSQL to create a new column that increments a GroupId each time a value does not match the previous row

This is a hard question for me to word but I was wondering if something like this is possible using psql. The general idea is I have a field called "label" which can contain any TEXT value. I am trying to group these with unique IDs that increment when the value of label is different than in the previous row.
Input Table
| RID | Label|
| ---- | ---- |
| 1 | |
| 2 | A |
| 3 | A |
| 4 | |
| 5 | |
| 6 | B |
| 7 | B |
| 8 | B |
| 9 | A |
|10 | A |
|11 | |
|12 | |
Desired Output Table
|RID|Label|Group ID|
|---|-----|--------|
| 1 | | 1 |
| 2 | A | 2 |
| 3 | A | 2 |
| 4 | | 3 |
| 5 | | 3 |
| 6 | B | 4 |
| 7 | B | 4 |
| 8 | B | 4 |
| 9 | A | 5 |
|10 | A | 5 |
|11 | | 6 |
|12 | | 6 |

How do I get around aggregate function error?

I have the following sql to calculate a % total:
SELECT tblTourns_atp.ID_Ti,
Sum([FS_1]/(SELECT Sum(FSOF_1)
FROM stat_atp
WHERE stat_atp.ID_T = tblTourns_atp.ID_T)) AS S1_IP
FROM stat_atp
INNER JOIN tblTourns_atp ON stat_atp.ID_T = tblTourns_atp.ID_T
GROUP BY tblTourns_atp.ID_Ti
I'm getting the 'aggregate error' because it wants the ID_T fields either grouped or in an aggregate function. I've read loads of examples but none of them seem to apply when the offending field is the subject of 'WHERE'.
Tables and output as follows:
+----------+------+--------+--+---------------+-------+--+--------+--------+
| stat_atp | | | | tblTourns_atp | | | Output | |
+----------+------+--------+--+---------------+-------+--+--------+--------+
| ID_T | FS_1 | FSOF_1 | | ID_T | ID_Ti | | ID_Ti | S1_IP |
| 1 | 20 | 40 | | 1 | 1 | | 1 | 31.03% |
| 2 | 30 | 100 | | 2 | 1 | | 2 | 28.57% |
| 3 | 40 | 150 | | 3 | 1 | | 3 | 33.33% |
| 4 | 30 | 100 | | 4 | 2 | | | |
| 5 | 30 | 100 | | 5 | 2 | | | |
| 6 | 40 | 150 | | 6 | 2 | | | |
| 7 | 20 | 40 | | 7 | 3 | | | |
| 8 | 30 | 100 | | 8 | 3 | | | |
| 9 | 40 | 150 | | 9 | 3 | | | |
| 10 | 20 | 40 | | 10 | 3 | | | |
+----------+------+--------+--+---------------+-------+--+--------+--------+
Since you already have an inner join between the two tables, a separate subquery isn't required:
select t.id_ti, sum(s.fs_1)/sum(s.fsof_1) as pct
from tbltourns_atp t inner join stat_atp s on t.id_t = s.id_t
group by t.id_ti

Oracle: get countries separated by N borders

I would like to get all countries separated by N (1,2,3,4 ...) borders from a specified country.
N should also be specified.
For example I have the table "borders" and "country":
border | neighbor
-----------------
FR | DE
FR | IT
IT | FR
DE | FR
DE | PL
PL | DE
DE | DK
DK | DE
CODE COUNTRYNAME
---- ---------
FR France
DE Germany
RU Russia
IT Italy
PL Poland
DK Denmark
N = 2 & country = France
If I want to get countries separated by 2 borders from France, it should return Poland (FR -> DE -> PL) and Denmark (FR -> DE -> DK)
N = 1 & country = France
If I want to get countries separated by 1 border from France, it should return Germany (FR -> DE) and Italy (FR -> IT)
I can modify borders if needed.
I tried some hierarchical queries without success.
Thanks
BR
Here's a complete enumeration of all possible paths and their lengths, given a starting country and no limitation as to paths being the shortest possible paths between two countries (disclaimer, don't run this on too many countries):
WITH
countries AS (SELECT DISTINCT border country FROM t),
chains (country, path, destination, steps) AS (
SELECT country, country, country, 0
FROM countries
UNION ALL
SELECT chains.country, chains.path || '->' || t.neighbor, t.neighbor, chains.steps + 1
FROM chains
JOIN t ON chains.destination = t.border
AND chains.path NOT LIKE '%' || t.neighbor || '%' -- This prevents cycles
)
SELECT *
FROM chains
ORDER BY country, steps;
The result being:
| COUNTRY | PATH | DESTINATION | STEPS |
|---------|----------------|-------------|-------|
| DE | DE | DE | 0 |
| DE | DE->PL | PL | 1 |
| DE | DE->FR | FR | 1 |
| DE | DE->DK | DK | 1 |
| DE | DE->FR->IT | IT | 2 |
| DK | DK | DK | 0 |
| DK | DK->DE | DE | 1 |
| DK | DK->DE->FR | FR | 2 |
| DK | DK->DE->PL | PL | 2 |
| DK | DK->DE->FR->IT | IT | 3 |
| FR | FR | FR | 0 |
| FR | FR->IT | IT | 1 |
| FR | FR->DE | DE | 1 |
| FR | FR->DE->DK | DK | 2 |
| FR | FR->DE->PL | PL | 2 |
| IT | IT | IT | 0 |
| IT | IT->FR | FR | 1 |
| IT | IT->FR->DE | DE | 2 |
| IT | IT->FR->DE->PL | PL | 3 |
| IT | IT->FR->DE->DK | DK | 3 |
| PL | PL | PL | 0 |
| PL | PL->DE | DE | 1 |
| PL | PL->DE->FR | FR | 2 |
| PL | PL->DE->DK | DK | 2 |
| PL | PL->DE->FR->IT | IT | 3 |
SQLFiddle here.
Store the query in a view and then you can filter on it, e.g.
SELECT * FROM my_view WHERE country = 'FR' AND steps = 2
Side-note on shortest paths:
If you actually did need the shortest paths between two countries, just reuse
that view again picking an arbitrary path when two paths tie (again, this isn't the most efficient solution, don't do this for too many countries!):
SELECT
country,
destination,
MIN(steps) KEEP (DENSE_RANK FIRST ORDER BY steps) AS steps,
MIN(path) KEEP (DENSE_RANK FIRST ORDER BY steps) AS path
FROM paths
WHERE country != destination
GROUP BY country, destination
ORDER BY country, destination
And get:
| COUNTRY | DESTINATION | STEPS | PATH |
|---------|-------------|-------|----------------|
| DE | DK | 1 | DE->DK |
| DE | FR | 1 | DE->FR |
| DE | IT | 2 | DE->FR->IT |
| DE | PL | 1 | DE->PL |
| DK | DE | 1 | DK->DE |
| DK | FR | 2 | DK->DE->FR |
| DK | IT | 3 | DK->DE->FR->IT |
| DK | PL | 2 | DK->DE->PL |
| FR | DE | 1 | FR->DE |
| FR | DK | 2 | FR->DE->DK |
| FR | IT | 1 | FR->IT |
| FR | PL | 2 | FR->DE->PL |
| IT | DE | 2 | IT->FR->DE |
| IT | DK | 3 | IT->FR->DE->DK |
| IT | FR | 1 | IT->FR |
| IT | PL | 3 | IT->FR->DE->PL |
| PL | DE | 1 | PL->DE |
| PL | DK | 2 | PL->DE->DK |
| PL | FR | 2 | PL->DE->FR |
| PL | IT | 3 | PL->DE->FR->IT |
As can be seen in this SQL Fiddle, or again, with a bit more data.
You can aggregate the neighbours of each country into a collection and then use a simple hierarchical query to find the (non-cyclic) paths:
SQL Fiddle
Oracle 11g R2 Schema Setup:
create table borders (border char(2), neighbor char(2));
insert into borders values ('FR','DE');
insert into borders values ('FR','IT');
insert into borders values ('IT','FR');
insert into borders values ('DE','FR');
insert into borders values ('DE','PL');
insert into borders values ('PL','DE');
insert into borders values ('DE','DK');
insert into borders values ('DK','DE');
insert into borders values ('RU','PL');
insert into borders values ('PL','RU');
insert into borders values ('IT','CH');
insert into borders values ('FR','CH');
insert into borders values ('DE','CH');
insert into borders values ('CH','IT');
insert into borders values ('CH','FR');
insert into borders values ('CH','DE');
CREATE TYPE countrylist AS TABLE OF CHAR(2);
Query 1:
WITH neighbors ( country, neighbors ) AS (
SELECT border,
CAST( COLLECT( neighbor ) AS COUNTRYLIST )
FROM borders
GROUP BY border
)
SELECT SYS_CONNECT_BY_PATH( country, '->' ) AS path,
CONNECT_BY_ROOT( country ) AS origin,
country AS destination,
LEVEL - 1 AS path_length
FROM neighbors
WHERE LEVEL - 1 = 4 -- Remove this to find paths of any length
START WITH country = 'FR' -- Remove this to start from any country
CONNECT BY NOCYCLE
country MEMBER OF PRIOR neighbors
Results:
| PATH | ORIGIN | DESTINATION | PATH_LENGTH |
|----------------------|--------|-------------|-------------|
| ->FR->CH->DE->PL->RU | FR | RU | 4 |
| ->FR->IT->CH->DE->DK | FR | DK | 4 |
| ->FR->IT->CH->DE->PL | FR | PL | 4 |
Explain Plan:
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16 | 608 | 5 | 00:00:01 |
| * 1 | FILTER | | | | | |
| * 2 | CONNECT BY NO FILTERING WITH START-WITH | | | | | |
| 3 | VIEW | | 16 | 608 | 4 | 00:00:01 |
| 4 | SORT GROUP BY | | 16 | 128 | 4 | 00:00:01 |
| 5 | TABLE ACCESS FULL | BORDERS | 16 | 128 | 3 | 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter(LEVEL-1=4)
* 2 - filter("COUNTRY"MEMBER OFPRIOR "NEIGHBORS" AND "COUNTRY"='FR')
Query 2 This will get the shortest path (with ties) between pairs of countries:
WITH neighbors ( country, neighbors ) AS (
SELECT border,
CAST( COLLECT( neighbor ) AS COUNTRYLIST )
FROM borders
GROUP BY border
)
SELECT path,
origin,
destination,
path_length
FROM (
SELECT SYS_CONNECT_BY_PATH( country, '->' ) AS path,
CONNECT_BY_ROOT( country ) AS origin,
country AS destination,
LEVEL - 1 AS path_length,
RANK() OVER (
PARTITION BY CONNECT_BY_ROOT( country ), country
ORDER BY LEVEL ASC
) AS path_length_rank
FROM neighbors
WHERE LEVEL > 1
CONNECT BY NOCYCLE
country MEMBER OF PRIOR neighbors
ORDER BY origin, destination
)
WHERE path_length_rank = 1
Results:
| PATH | ORIGIN | DESTINATION | PATH_LENGTH |
|----------------------|--------|-------------|-------------|
| ->CH->DE | CH | DE | 1 |
| ->CH->DE->DK | CH | DK | 2 |
| ->CH->FR | CH | FR | 1 |
| ->CH->IT | CH | IT | 1 |
| ->CH->DE->PL | CH | PL | 2 |
| ->CH->DE->PL->RU | CH | RU | 3 |
| ->DE->CH | DE | CH | 1 |
| ->DE->DK | DE | DK | 1 |
| ->DE->FR | DE | FR | 1 |
| ->DE->FR->IT | DE | IT | 2 |
| ->DE->CH->IT | DE | IT | 2 |
| ->DE->PL | DE | PL | 1 |
| ->DE->PL->RU | DE | RU | 2 |
| ->DK->DE->CH | DK | CH | 2 |
| ->DK->DE | DK | DE | 1 |
| ->DK->DE->FR | DK | FR | 2 |
| ->DK->DE->FR->IT | DK | IT | 3 |
| ->DK->DE->CH->IT | DK | IT | 3 |
| ->DK->DE->PL | DK | PL | 2 |
| ->DK->DE->PL->RU | DK | RU | 3 |
| ->FR->CH | FR | CH | 1 |
| ->FR->DE | FR | DE | 1 |
| ->FR->DE->DK | FR | DK | 2 |
| ->FR->IT | FR | IT | 1 |
| ->FR->DE->PL | FR | PL | 2 |
| ->FR->DE->PL->RU | FR | RU | 3 |
| ->IT->CH | IT | CH | 1 |
| ->IT->FR->DE | IT | DE | 2 |
| ->IT->CH->DE | IT | DE | 2 |
| ->IT->CH->DE->DK | IT | DK | 3 |
| ->IT->FR->DE->DK | IT | DK | 3 |
| ->IT->FR | IT | FR | 1 |
| ->IT->CH->DE->PL | IT | PL | 3 |
| ->IT->FR->DE->PL | IT | PL | 3 |
| ->IT->FR->DE->PL->RU | IT | RU | 4 |
| ->IT->CH->DE->PL->RU | IT | RU | 4 |
| ->PL->DE->CH | PL | CH | 2 |
| ->PL->DE | PL | DE | 1 |
| ->PL->DE->DK | PL | DK | 2 |
| ->PL->DE->FR | PL | FR | 2 |
| ->PL->DE->CH->IT | PL | IT | 3 |
| ->PL->DE->FR->IT | PL | IT | 3 |
| ->PL->RU | PL | RU | 1 |
| ->RU->PL->DE->CH | RU | CH | 3 |
| ->RU->PL->DE | RU | DE | 2 |
| ->RU->PL->DE->DK | RU | DK | 3 |
| ->RU->PL->DE->FR | RU | FR | 3 |
| ->RU->PL->DE->FR->IT | RU | IT | 4 |
| ->RU->PL->DE->CH->IT | RU | IT | 4 |
| ->RU->PL | RU | PL | 1 |
Explain Plan:
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16 | 32576 | 6 | 00:00:01 |
| * 1 | VIEW | | 16 | 32576 | 6 | 00:00:01 |
| 2 | SORT ORDER BY | | 16 | 608 | 6 | 00:00:01 |
| * 3 | WINDOW SORT PUSHED RANK | | 16 | 608 | 6 | 00:00:01 |
| * 4 | FILTER | | | | | |
| * 5 | CONNECT BY WITHOUT FILTERING | | | | | |
| 6 | VIEW | | 16 | 608 | 4 | 00:00:01 |
| 7 | SORT GROUP BY | | 16 | 128 | 4 | 00:00:01 |
| 8 | TABLE ACCESS FULL | BORDERS | 16 | 128 | 3 | 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter("PATH_LENGTH_RANK"=1)
* 3 - filter(RANK() OVER ( PARTITION BY ANY,"COUNTRY" ORDER BY LEVEL)<=1)
* 4 - filter(LEVEL>1)
* 5 - filter("COUNTRY"MEMBER OFPRIOR "NEIGHBORS")
Your BORDERS table contains reciprocal relationships (e.g. FR->DE, DE->FR) . This means you need to handle cycles. This is not straightforward at all, because you want to avoid say FR->DE->PL->DE at three degrees of separation.
I have here a recursive WITH clause, (so Oracle 11gR2 or later) which does this.
with hqry (path, nghbr, prev_bdr, root_bdr, lvl) as (
select b.border
, b.neighbor
, b.border
, b.border
, 1 as lvl
from borders b
where b.border = 'FR'
union all
select hqry.path || '->' || b.border
, b.neighbor
, hqry.nghbr
, hqry.root_bdr
, hqry.lvl + 1
from hqry
join borders b on b.border = hqry.nghbr
where b.neighbor != hqry.root_bdr
and b.neighbor != hqry.prev_bdr
and hqry.lvl < 3 -- this is a nasty kludge, with more time I'd like to fix it
)
SEARCH DEPTH FIRST BY path SET order1
CYCLE path SET cycle TO 1 DEFAULT 0
select path || '->' || nghbr as end_path
from hqry
where hqry.lvl = 3
;
It takes five parameters
path - the previous chain of borders
nghbr - the current neighbor, stating with the root country i.e. France
prev_bdr - the immediate previous border to prevent FR->DE->PL->DE
root_bdr - the originating border to prevent FR->CH->IT->FR
lvl - to track the degrees of separation
Sample output for three degrees of separation:
FR->CH->DE->DK
FR->CH->DE->PL
FR->DE->CH->IT
FR->DE->PL->RU
FR->IT->CH->DE
There is a SQL Fiddle demo here. I added in a couple more countries: Switzerland adds some nasty edges cases.
Obviously the above output shows it doesn't enforce the shortest path algorithm, that is left as an exercise for the reader :) If you're interested in adding this - and you should be, because I think it's key to a robust solution - I suggest you real this post by Lucas Jellema.
You could use CONNECT_BY_ROOT to find the neighbors and filter by LEVEL to find the nth neighbor.
SELECT *
FROM (
SELECT border
,connect_by_root(neighbor) AS neighbor
FROM borders
WHERE border = :ctry
AND LEVEL = :n
CONNECT BY NOCYCLE
PRIOR border = neighbor
) WHERE neighbor != :ctry
Demo

Inefficient SQL Search Query - Oracle DB

My logic in this query is right (well im 80% sure it is). but its been running for 2h 23min and still going, was wondering if some one could maybe help me make this run a bit more efficiently as i don't think its that intense of a query
SELECT b.bridge_no, COUNT(*) AS comment_cnt
FROM iacd_asset b INNER JOIN iacd_note c
ON REGEXP_LIKE(c.comments, '(^|\W)BN' || b.bridge_no || '(\W|$)', 'i')
inner join ncr_note e on c.note_id=e.note_id
inner join ncr f on e.ncr_id=f.ncr_id
inner join ncr_iac g on f.ncr_id=g.ncr_id
WHERE c.create_dt >= date'2015-01-01'
AND c.create_dt < date'2015-03-12'
AND length(b.bridge_no) > 1
AND g.scheme in (1, 3, 5, 6, 7, 8, 9, 9, and about 10 more values)
GROUP BY b.bridge_no
ORDER BY comment_cnt;
in short the query should be making a bunch of joins, and then filtering the joined table by schemes (g.scheme in....) , and then parsing the notes field for anything with BN in it.
PLAN TABLE, ok i have never used one before, but i believe this is the plan table
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| OPERATION | OPTIONS | OBJECT_OWNER | OBJECT_NAME | OBJECT_ALIAS | OBJECT_INSTANCE | OBJECT_TYPE | OPTIMIZER | ID | PARENT_ID | DEPTH | POSITION | COST | CARDINALITY | BYTES | CPU_COST | IO_COST | TEMP_SPACE | ACCESS_PREDICATES | FILTER_PREDICATES | PROJECTION | TIME | QBLOCK_NAME |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| SELECT STATEMENT | | | | | | | ALL_ROWS | 0 | | 0 | 281,503 | 281,503 | 40 | 4,480 | 148,378,917,975 | 215,677 | | | | | 458 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| SORT | ORDER BY | | | | | | | 1 | 0 | 1 | 1 | 281,503 | 40 | 4,480 | 148,378,917,975 | 215,677 | | | | (#keys=1) COUNT(*)[22], "B"."BRIDGE_NO"[NUMBER,22] | 458 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| HASH | GROUP BY | | | | | | | 2 | 1 | 2 | 1 | 281,503 | 40 | 4,480 | 148,378,917,975 | 215,677 | | | | (#keys=1) "B"."BRIDGE_NO"[NUMBER,22], COUNT(*)[22] | 458 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| HASH JOIN | | | | | | | | 3 | 2 | 3 | 1 | 281,497 | 16,084 | 1,801,408 | 148,366,537,976 | 215,677 | 24,126,000 | "G"."NCR_ID"="F"."NCR_ID" | | (#keys=1) "B"."BRIDGE_NO"[NUMBER,22] | 458 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| HASH JOIN | | | | | | | | 4 | 3 | 4 | 1 | 96,996 | 209,778 | 21,607,134 | 13,549,630,814 | 90,985 | 22,725,000 | "E"."NCR_ID"="F"."NCR_ID" | | (#keys=1) "F"."NCR_ID"[NUMBER,22], "B"."BRIDGE_NO"[NUMBER,22] | 158 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| HASH JOIN | | | | | | | | 5 | 4 | 5 | 1 | 42,595 | 208,419 | 20,216,643 | 5,484,063,163 | 40,162 | 9,839,000 | "C"."NOTE_ID"="E"."NOTE_ID" | REGEXP_LIKE ("C"."COMMENTS",'(^|\W)BN'||TO_CHAR("B"."BRIDGE_NO")||'(\W|$)','i') | (#keys=1) "B"."BRIDGE_NO"[NUMBER,22], "E"."NCR_ID"[NUMBER,22] | 70 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| PARTITION RANGE | SINGLE | | | | | | | 6 | 5 | 6 | 1 | 1,039 | 104,603 | 8,577,446 | 62,280,224 | 1,011 | | | | "C"."NOTE_ID"[NUMBER,22], "C"."COMMENTS"[VARCHAR2,4000] | 2 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| TABLE ACCESS | FULL | IACDB | IACD_NOTE | C#SEL$1 | 2 | TABLE | ANALYZED | 7 | 6 | 7 | 1 | 1,039 | 104,603 | 8,577,446 | 62,280,224 | 1,011 | | | "C"."CREATE_DATE"<TO_DATE(' 2014-12-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss') | "C"."NOTE_ID"[NUMBER,22], "C"."COMMENTS"[VARCHAR2,4000] | 2 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| MERGE JOIN | CARTESIAN | | | | | | | 8 | 5 | 6 | 2 | 24,267 | 12,268,270 | 184,024,050 | 2,780,501,758 | 23,033 | | | | (#keys=0) "B"."BRIDGE_NO"[NUMBER,22], "E"."NCR_ID"[NUMBER,22], "E"."NOTE_ID"[NUMBER,22] | 40 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| TABLE ACCESS | FULL | IACDB | IACD_ASSET | B#SEL$1 | 1 | TABLE | ANALYZED | 9 | 8 | 7 | 1 | 7 | 40 | 160 | 560,542 | 7 | | | LENGTH(TO_CHAR("B"."BRIDGE_NO"))>1 | "B"."BRIDGE_NO"[NUMBER,22] | 1 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| BUFFER | SORT | | | | | | | 10 | 8 | 7 | 2 | 24,259 | 308,248 | 3,390,728 | 2,779,941,216 | 23,026 | | | | (#keys=0) "E"."NCR_ID"[NUMBER,22], "E"."NOTE_ID"[NUMBER,22] | 40 | |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| TABLE ACCESS | FULL | IACDB | IACD_NCR_NOTE | E#SEL$2 | 4 | TABLE | ANALYZED | 11 | 10 | 8 | 1 | 606 | 308,248 | 3,390,728 | 69,498,530 | 576 | | | | "E"."NCR_ID"[NUMBER,22], "E"."NOTE_ID"[NUMBER,22] | 1 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| INDEX | FAST FULL SCAN | IACDB | PK_IACDNCR_NCRID | F#SEL$3 | | INDEX (UNIQUE) | ANALYZED | 12 | 4 | 5 | 2 | 31,763 | 22,838,996 | 137,033,976 | 3,248,120,913 | 30,322 | | | | "F"."NCR_ID"[NUMBER,22] | 52 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
| TABLE ACCESS | FULL | IACDB | IACD_NCR_IAC | G#SEL$4 | 8 | TABLE | ANALYZED | 13 | 3 | 4 | 2 | 181,461 | 1,731,062 | 15,579,558 | 134,407,812,606 | 121,833 | | | ALL THE SCHEMES CHCECKS | "G"."NCR_ID"[NUMBER,22] | 295 | SEL$81719215 |
+------------------+----------------+--------------+------------------+--------------+-----------------+----------------+-----------+----+-----------+-------+----------+---------+-------------+-------------+-----------------+---------+------------+-----------------------------+---------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+------+--------------+
Hopefully thats legible enough
interms of indexes i assume only the fields that are being sorted is importent
crate_dt is not indexed
scheme id is indexed
Maybe my order in query is wrong...
The plan shows you're doing FULL TABLE SCAN of IACD_NOTE and IACD_ASSET, and then doing a CARETESIAN join of them, because you have provided no criteria for linking one record in IACD_ASSET to a set of records in IACD_NOTE.
That's not my definition of a non-intense query, and the eye-popping values for CPU cost bear that out.
You need to replace this ..,
FROM iacd_asset b INNER JOIN iacd_note c
ON REGEXP_LIKE(c.comments, '(^|\W)BN' || b.bridge_no || '(\W|$)', 'i')
... with an actual join on indexed columns. It would be helpful if Notes were linked to Assets by a foreign key of BRIDGE_NO or similar. I don't know your data model. Then you can use that regex as an additional filter in the WHERE clause.
Also you join to three further tables, to get to something which allows an additional filter on SCHEME. Again, I don't know your data model but this seems pretty inefficient.
Unfortunately this is the sort of tuning which relies on domain knowledge. Fixing this query requires understanding of the data - its volume, distribution and skew, the data model itself and the business logic your query implements. This is way beyond the scope of the advice we can offer in StackOverflow.
One thing to consider, but it is a big decision would be to index the comments with a free text index. However, that has lots of ramifications (especially space and database admin). Find out more.

Running total SQL server - AGAIN

i'm aware that this question has been asked multiple times and I have read those threads to get to where I am now, but those solutions don't seem to be working. I need to have a running total of my ExpectedAmount...
I have the following table:
+--------------+----------------+
| ExpectedDate | ExpectedAmount |
+--------------+----------------+
| 1 | 2485513 |
| 2 | 526032 |
| 3 | 342041 |
| 4 | 195807 |
| 5 | 380477 |
| 6 | 102233 |
| 7 | 539951 |
| 8 | 107145 |
| 10 | 165110 |
| 11 | 18795 |
| 12 | 27177 |
| 13 | 28232 |
| 14 | 154631 |
| 15 | 5566585 |
| 16 | 250814 |
| 17 | 90444 |
| 18 | 105424 |
| 19 | 62132 |
| 20 | 1799349 |
| 21 | 303131 |
| 22 | 459464 |
| 23 | 723488 |
| 24 | 676514 |
| 25 | 17311911 |
| 26 | 4876062 |
| 27 | 4844434 |
| 28 | 4039687 |
| 29 | 1418648 |
| 30 | 4366189 |
| 31 | 9028836 |
+--------------+----------------+
I have the following SQL:
SELECT a.ExpectedDate, a.ExpectedAmount, (SELECT SUM(b.ExpectedAmount)
FROM UnpaidManagement..Expected b
WHERE b.ExpectedDate <= a.ExpectedDate)
FROM UnpaidManagement..Expected a
The result of the above SQL is this:
+--------------+----------------+--------------+
| ExpectedDate | ExpectedAmount | RunningTotal |
+--------------+----------------+--------------+
| 1 | 2485513 | 2485513 |
| 2 | 526032 | 9480889 |
| 3 | 342041 | 46275618 |
| 4 | 195807 | 59866450 |
| 5 | 380477 | 60246927 |
| 6 | 102233 | 60349160 |
| 7 | 539951 | 60889111 |
| 8 | 107145 | 60996256 |
| 10 | 165110 | 2650623 |
| 11 | 18795 | 2669418 |
| 12 | 27177 | 2696595 |
| 13 | 28232 | 2724827 |
| 14 | 154631 | 2879458 |
| 15 | 5566585 | 8446043 |
| 16 | 250814 | 8696857 |
| 17 | 90444 | 8787301 |
| 18 | 105424 | 8892725 |
| 19 | 62132 | 8954857 |
| 20 | 1799349 | 11280238 |
| 21 | 303131 | 11583369 |
| 22 | 459464 | 12042833 |
| 23 | 723488 | 12766321 |
| 24 | 676514 | 13442835 |
| 25 | 17311911 | 30754746 |
| 26 | 4876062 | 35630808 |
| 27 | 4844434 | 40475242 |
| 28 | 4039687 | 44514929 |
| 29 | 1418648 | 45933577 |
| 30 | 4366189 | 50641807 |
| 31 | 9028836 | 59670643 |
+--------------+----------------+--------------+
You can tell from the first few values already that the math is all off, but then at some points the math adds up?! I'm Too confused !! Could someone please point me to another solution or to where I have gone wrong with this?
I am using SQL Server 2008.
It is because your ExpectedDate column of type varchar. Try this:
SELECT a.ExpectedDate, a.ExpectedAmount, (SELECT SUM(b.ExpectedAmount)
FROM UnpaidManagement..Expected b
WHERE CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int))
FROM UnpaidManagement..Expected a
Note that it could be inefficient query.
I think this gonna work:
SELECT a.ExpectedDate,
a.ExpectedAmount,
SUM(b.ExpectedAmount) RuningTotal
FROM UnpaidManagement..Expected a
LEFT JOIN UnpaidManagement..Expected b
ON CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int)
GROUP BY a.ExpectedDate, a.ExpectedAmount
AND:
SELECT a.ExpectedDate,
a.ExpectedAmount,
c.RuningTotal
FROM UnpaidManagement..Expected a
CROSS APPLY (
SELECT SUM(b.ExpectedAmount) AS RuningTotal
FROM UnpaidManagement..Expected b
WHERE CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int)
) c