Hello,
I hope this kind of question is allowed; also, thank you a lot in advance for reading. ^-^
I am trying to write a N1QL query that gets in the result the minimum of a count with another field . As far as I know, the only way to do so is to use the same subquery twice, in this way:
SELECT subquery.parameter, subquery.count
FROM /* <SUBQUERY>, with a field "count" that is a COUNT(*) of other stuff*/ AS subquery
WHERE subquery.count WITHIN (SELECT MIN(...) FROM /*<SUBQUERY>*/)
(I’m using a pseudo-query to simplify things, but I’ll paste my actual query at the end just to be safe.)
I can confirm that this works on my database, even if it’s very long and unreadable.
The subquery is quite long, so my question is: as it’s used identically twice, is there some way to “save” the subquery and use it in both the FROM and the SELECT clause? I come from an SQL background, so what I’m asking is if there is a way to create views (but I mean this in the SQL sense, not in the MapReduce/Couchbase sense).
If this is possible, I have a further question: is there a way to make it so that Couchbase will execute the subquery only once and then reuse it (aka, I’m saving the result itself) in both the FROM and SELECT?
I am working closely with the documentation, but all I have found is the LET construct - which, as far as understand, only deals with variables - and some people suggest using indexes but I don’t see how I would use them here; hence I’m asking.
Thank you a lot for your time. I’m attaching the query, but be wary it’s quite long; however, you can se most of it is the same subquery being repeated.
/*CREATE INDEX idx_poiname IF NOT EXISTS ON veronacard.veronacard_db.mini_POI_db(name);
/*this is necessary for the outer join*/
SELECT daily_count.name, daily_count.countedswipes
FROM ( /*SUBQUERY: find swipes count on 9/8/20 for every POI*/
SELECT POInames.name,IFMISSINGORNULL(partial_count.countedswipes,0) AS countedswipes
/* I need this because otherwise if the POI has no swipes, it will not be included (like this, instead, it will be included with swipescount = 0) */
FROM (
SELECT POI1.name AS poiname, COUNT(*) AS countedswipes
FROM veronacard.veronacard_db.mini_POI_db AS POI1 UNNEST POI1.swipes AS S1
WHERE
DATE_PART_STR(S1.swipe_date, "year") = 2020 AND
DATE_PART_STR(S1.swipe_date, "month") = 8 AND
DATE_PART_STR(S1.swipe_date, "day") = 9
GROUP BY POI1.name
) AS partial_count
RIGHT JOIN (SELECT DISTINCT POI.name FROM veronacard.veronacard_db.mini_POI_db AS POI)
AS POInames ON partial_count.poiname == POInames.name
) AS daily_count
WHERE daily_count.countedswipes WITHIN (
SELECT MIN (daily_count1.countedswipes)
FROM(
SELECT POInames.name,IFMISSINGORNULL(partial_count.countedswipes,0) AS countedswipes
FROM ( /*SUBQUERY AGAIN*/
SELECT POI1.name AS poiname, COUNT(*) AS countedswipes
FROM veronacard.veronacard_db.mini_POI_db AS POI1 UNNEST POI1.swipes AS S1
WHERE
DATE_PART_STR(S1.swipe_date, "year") = 2020 AND
DATE_PART_STR(S1.swipe_date, "month") = 8 AND
DATE_PART_STR(S1.swipe_date, "day") = 9
GROUP BY POI1.name
) AS partial_count
RIGHT JOIN (SELECT DISTINCT POI.name FROM veronacard.veronacard_db.mini_POI_db AS POI)
AS POInames ON partial_count.poiname == POInames.name
) AS daily_count1
)