Cypher - Issue with Where + Aggregate + With - cypher

I am trying to execute the following Cypher query
START b=node:customer_idx(ID = 'ABCD')
MATCH p = b-[r1:LIKES]->stuff, someone_else_too-[r2:LIKES]->stuff
with b,someone_else_too, count(*) as matchingstuffcount
where matchingstuffcount > 1
//with b, someone_else_too, matchingstuffcount, CASE WHEN ...that has r1, r2... END as SortIndex
return someone_else_too, SortIndex
order by SortIndex
The above query works fine but moment I uncomment lower "with" I get following errors
Unknown identifier `b`.
Unknown identifier `someone_else_too`.
Unknown identifier `matchingstuffcount`.
Unknown identifier `r1`.
Unknown identifier `r2`.
To get around, I include r1 and r2 in the top with - "with b,someone_else_too, count(*) as matchingstuffcount". to "with b, r1, r2, someone_else_too, count(*) as matchingstuffcount". This messes my count(*) > 1 condition as count(*) does not aggregate properly.
Any workarounds / suggestions to filter out count(*) > 1 while making sure Case When can also be executed ?

Under neo4j 2.0 via console.neo4j.org I was able to get the following query to work. I tried to mimic the constructs you had, namely the WITH/WHERE/WITH/RETURN sequence. (If I missed something, please let me know!)
START n=node:node_auto_index(name='Neo')
MATCH n-[r:KNOWS|LOVES*]->m
WITH n,COUNT(r) AS cnt,m
WHERE cnt >1
WITH n, cnt, m, CASE WHEN m.name?='Cypher' THEN 1 ELSE 0 END AS isCypher
RETURN n AS Neo, cnt, m, isCypher
ORDER BY cnt
Update it or change it here.

Related

Oracle SQL Statement - Identify & Count Unique Callers

I'm looking to make some improvements to our telephony call data - and have a requirement to identify if a CALLER is unique - if they call more than once on a given date (CALL_DATE) - it flags as a 1 value, if only once a 0 value.
Any ideas how I can modify this existing statement to reflect this?
SELECT /*+ PARALLEL (4) */
A.CALL_ID,
A.CALL_DATE,
O.OT_OUTLET_CODE,
A.CALL_TIME,
TO_CHAR(TO_DATE(A.CALL_TIME, 'HH24:MI:SS')+A.TALK_TIME/(24*60*60),'HH24:MI:SS') "CALL_END_TIME",
A.TALK_TIME,
A.RING_TIME,
A.OUTCOME,
CASE WHEN A.TRANSFER_TO = '10000' THEN 1 ELSE 0 END AS "VOICEMAIL"
FROM
OWBI.ODS_FACT_TIGER_TELEPHONY A,
OWBI.WHS_DIM_CAL_DATE C,
OWBI.WHS_DIM_OUTLET O
WHERE
A.CALL_DATE = C.CD_DAY_DATE
AND A.WHS_DIM_OUTLET = O.DIMENSION_KEY
AND C.EY_YEAR_CODE IN ('2019')
AND C.EW_WEEK_IN_YEAR IN ('1') -- **FILTER ON PREVIOUS BUSINESS WEEK NUMBER**
ORDER BY A.CALL_DATE DESC;
What you are describing sounds like a job for the analytic count(*) function.
Add this to the SELECT clause and don't change anything else:
case when count(*) over (partition by a.call_id, a.call_date) = 1 then 0
else 1 end as unique_flag

Postgres SQL query doesn't identify the column

I'm having a huge problem with my query, for some reason I just can't get one of the WHERE clauses to work.
This is my SQL:
SELECT COUNT(*) FROM "diets" JOIN "meals" on "idDiet" = "dietId"
WHERE kcal != 0 AND "diets.createdAt" > '2016-10-2'
GROUP BY "userIdUser" HAVING count(*) >= 5;
And my error:
ERROR: column "diets.createdAt" does not exist
My scheme for both tables:
Any idea on what I must do for this query to work? Thank you very much, if more information is needed please let me know.
Your quotes are wrong:
SELECT COUNT(*)
FROM "diets" JOIN
"meals"
ON "idDiet" = "dietId"
WHERE kcal <> 0 AND "diets"."createdAt" > '2016-10-2'
GROUP BY "userIdUser"
HAVING count(*) >= 5;
The double quotes go around an identifier. A qualified column reference such as diets.createdAt consists of two identifiers, so each needs to have the quotes (if you have them at all).
Otherwise, you are referring to a column whose name is "diets.createdAt". That is, the column name would have a period in it.
SELECT COUNT(*) FROM diets a JOIN meals b on a.idDiet = b.dietId
WHERE a.kcal <> 0 AND a.createdAt > '2016-10-2'
GROUP BY a.userIdUser HAVING count(*) >= 5;

single-row subquery returns more than one row. Query not working with main query

I hve to display several cell values into one cell. So I am using this query:
select LISTAGG(fc.DESCRIPTION, ';'||chr(10))WITHIN GROUP (ORDER BY fc.SWITCH_NAME) AS DESCRIP from "ORS".SWITCH_OPERATIONS fc
group by fc.SWITCH_NAME
It is working fine. But when I am merging this with my main(complete) query then I am getting the error as: Error code 1427, SQL state 21000: ORA-01427: single-row subquery returns more than one row
Here is my complete query:
SELECT
TRACK_EVENT.LOCATION,
TRACK_EVENT.ELEMENT_NAME,
(select COUNT(*) from ORS.TRACK_EVENT b where (b.ELEMENT_NAME = sw.SWITCH_NAME)AND (b.ELEMENT_TYPE = 'SWITCH')AND (b.EVENT_TYPE = 'I')AND (b.ELEMENT_STATE = 'NORMAL' OR b.ELEMENT_STATE = 'REVERSE'))as COUNTER,
(select COUNT(*) from ORS.SWITCH_OPERATIONS fc where TRACK_EVENT.ELEMENT_NAME = fc.SWITCH_NAME and fc.NO_CORRESPONDENCE = 1 )as FAIL_COUNT,
(select MAX(cw.COMMAND_TIME) from ORS.SWITCH_OPERATIONS cw where ((TRACK_EVENT.ELEMENT_NAME = cw.SWITCH_NAME) and (cw.NO_CORRESPONDENCE = 1)) group by cw.SWITCH_NAME ) as FAILURE_DATE,
(select LISTAGG(fc.DESCRIPTION, ';'||chr(10))WITHIN GROUP (ORDER BY fc.SWITCH_NAME) AS DESCRIP from "ORS".SWITCH_OPERATIONS fc
group by fc.SWITCH_NAME)
FROM
ORS.SWITCH_OPERATIONS sw,
ORS.TRACK_EVENT TRACK_EVENT
WHERE
sw.SEQUENCE_ID = TRACK_EVENT.SEQUENCE_ID
Not only are subqueries in the SELECT list required to return exactly one row (or any time they're used for a singular comparison, like <, =, etc), but their use in that context tends to make the database execute them RBAR - Row-by-agonizing-row. That is, they're slower and consume more resources than they should.
Generally, unless the result set outside the subquery contains only a few rows, you want to construct subqueries as part of a table-reference. Ie, something like:
SELECT m.n, m.z, aliasForSomeTable.a, aliasForSomeTabe.bSum
FROM mainTable m
JOIN (SELECT a, SUM(b) AS bSum
FROM someTable
GROUP BY a) aliasForSomeTable
ON aliasForSomeTable.a = m.a
This benefits you in other ways to - it's easier to get multiple columns out of the same table-reference, for example.
Assuming that LISTAGG(...) can be included with other aggregate functions, you can change your query to look like this:
SELECT Track_Event.location, Track_Event.element_name,
Counted_Events.counter,
Failure.fail_count, Failure.failure_date, Failure.descrip
FROM ORS.Track_Event
JOIN ORS.Switch_Operations
ON Switch_Operations.sequence_id = Track_Event.sequence_id
LEFT JOIN (SELECT element_name, COUNT(*) AS counter
FROM ORS.Track_Event
WHERE element_type = 'SWITCH'
AND event_type = 'I'
AND element_state IN ('NORMAL', 'REVERSE')
GROUP BY element_name) Counted_Events
ON Counted_Events.element_name = Switch_Operations.swicth_name
LEFT JOIN (SELECT switch_name,
COUNT(CASE WHEN no_correspondence = 1 THEN '1' END) AS fail_count,
MAX(CASE WHEN no_correspondence = 1 THEN command_time END) AS failure_date,
LISTAGG(description, ';' || CHAR(10)) WITHIN GROUP (ORDER BY command_time) AS descrip
FROM ORS.Switch_Operations
GROUP BY switch_name) Failure
ON Failure.switch_name = Track_Event.element_name
This query was written to (attempt to) preserve the semantics of your original query. I'm not completely sure that's what you actually need but without sample starting data and desired results, I have no way to tell how else to improve this. For instance, I'm a little suspicious of the need of Switch_Operations in the outer query, and the fact that LISTAGG(...) is run over row where no_correspondence <> 1. I did change the ordering of LISTAGG(...), because the original column would not have done anything (because the order way the same as the grouping), so would not have been a stable sort.
Single-row subquery returns more than one row.
This error message is self descriptive.
Returned field can't have multiple values and your subquery returns more than one row.
In your complete query you specify fields to be returned. The last field expects single value from the subquery but gets multiple rows instead.
I have no clue about the data you're working with but either you have to ensure that subquery returns only one row or you have to redesign the wrapping query (possibly using joins when appropriate).

SQL - CountIf on a column

Trying to do some calculations via SQL on my iSeries and have the following conundrum: I need to count the number of times a certain value appears in a column. My select statement is as follows:
Select
MOTRAN.ORDNO, MOTRAN.OPSEQ, MOROUT.WKCTR, MOTRAN.TDATE,
MOTRAN.LBTIM, MOROUT.SRLHU, MOROUT.RLHTD, MOROUT.ACODT,
MOROUT.SCODT, MOROUT.ASTDT, MOMAST.SSTDT, MOMAST.FITWH,
MOMAST.FITEM,
CONCAT(MOTRAN.ORDNO, MOTRAN.OPSEQ) As CON,
count (Concat(MOTRAN.ORDNO, MOTRAN.OPSEQ) )As CountIF,
MOROUT.SRLHU / (count (Concat(MOTRAN.ORDNO, MOTRAN.OPSEQ))) as calc
*(snip)*
With this information, I'm trying to count the number of times a value in CON appears. I will need this to do some math with so it's kinda important. My count statement doesn't work properly as it reports a certain value as occurring once when I see it appears 8 times.
Try putting a CASE statement inside a SUM().
SUM(CASE WHEN value = 'something' THEN 1 ELSE 0 END)
This will count the number of rows where value = 'something'.
Similary...
SUM(CASE WHEN t1.val = CONCAT(t2.val, t3.val) THEN 1 ELSE 0 END)
If you're on a supported version of the OS, ie 6.1 or higher...
You might be able to make use of "grouping set" functionality. Particularly the ROLLUP clause.
I can't say for sure without more understanding of your data.
Otherwise, you're going to need to so something like
wth Cnt as (select ORDNO, OPSEQ, count(*) as NbrOccur
from MOTRAN
group by ORDNO, OPSEQ
)
Select
MOTRAN.ORDNO, MOTRAN.OPSEQ, MOROUT.WKCTR, MOTRAN.TDATE,
MOTRAN.LBTIM, MOROUT.SRLHU, MOROUT.RLHTD, MOROUT.ACODT,
MOROUT.SCODT, MOROUT.ASTDT, MOMAST.SSTDT, MOMAST.FITWH,
MOMAST.FITEM,
CONCAT(MOTRAN.ORDNO, MOTRAN.OPSEQ) As CON,
Cnt.NbrOccur,
MOROUT.SRLHU / Cnt.NbrOccur as calc
from
motran join Cnt on mortran.ordno = cnt.ordno and mortran.opseq = cnt.opseq
*(snip)*

How to do a counter SQL Server 2008?

I have been doing this
SELECT
movi.Usuario AS RowUsuario, movi.MovID, MIN(Art.Descripcion1),
MIN(com.ReferenciaExtra), MIN(com.Unidad), MIN(Art.UnidadCompra),
MIN(movi.FechaEmision),
error = CASE
WHEN MIN (com.Unidad) NOT LIKE
CASE
WHEN MIN (ar.Unidad) LIKE com.Unidad THEN art.Unidad
END
THEN 1
ELSE 0
END
FROM
CompraD com
INNER JOIN
Mov movi ON com.ID = movi.ID
INNER JOIN
Art ON com.Articulo = Art.Articulo
WHERE
movi.Mov = 'Requisicion
ORDER BY
movi.FechaEmision ASC
`when 'com.unidad' dont match with art.Unidad, add 1 or 0 if they match
SQL Server says:
incorrect syntax CASE
The incorrect syntax error is referring to the
error = CASE part.
It should be
CASE statement END AS error
However I'm not sure if that will solve your problem as the case statements looks a little odd to me but get that bit the right way around and then let us know of any further error messages.
Possibly...
SUM(CASE WHEN com.Unidad <> ar.Unidad THEN 1 ELSE 0 END AS error)
Also, you are missing a GROUP BY clause, if you want to use aggregate functions (MIN for example) you need to GROUP BY the non aggregate fields.
You have WHEN MIN (ar.Unidad) LIKE com.Unidad THEN art.Unidad but I do not see ar aliased anywhere.
Also you need to either have GROUP BY or OVER clause with your MINs.
If you want more details you'll have to give more details and context.