Knex.js MYSQL WHERE or UNION

时间:2018-02-03 08:39:07

标签: mysql sql knex.js

I am having a hard time thinking through this query. I just don't know MYSQL well enough. I have two tables - one with school information and another with review information.

I am trying to return a table list of all schools in a selected country (a user clicks on a map and this calls that query). The table lists some school information and an average review score. In my review table I have a column that determines whether the review is "active" or not. Meaning has the user finished and published it.

I am able to get a list of the schools with an average total and it will include schools that do not have a review, but it also includes reviews in the average that are not "published" (it just shows null and that's fine because I can deal with that later). I can also get a query that lists the schools and and the correct average, but it filters out the schools that do not have reviews (because there is no column with the value of "1").

I am struggling to think through how to get the data I need. I know the issue is with the WHERE active="1" part, but I feel I need a UNION to connect the data.

I am trying to get a list of all the schools in a country, and an average score if there is one - and only average reviews that are set as active, and still return the schools if it does not have a review.

This is the query I am working with:

//This gives me all of the schools with an average, but filters the schools with out a review

  knex.select('schools.SID','schools.schoolName','schools.schoolCity',    
  knex.raw('ROUND(AVG(((Q1+Q2+Q3+Q4+Q5+Q6+Q7+Q8+Q9+Q10)/(52*10)*10)),2) AS average'))
    .from('reviews')
    .rightJoin('schools', 'schools.SID', 'reviews.schoolID')
    .where('schools.schoolCountryCode', countryId)
    .andWhere('reviews.active', '=', 1)
    .groupBy('schools.SID')
    .orderByRaw('average DESC, schools.schoolCity ASC')


//By commenting out the andWhere I get all of the schools and an average, but it includes the reviews in the average that are not published. 

  knex.select('schools.SID','schools.schoolName','schools.schoolCity',    
  knex.raw('ROUND(AVG(((Q1+Q2+Q3+Q4+Q5+Q6+Q7+Q8+Q9+Q10)/(52*10)*10)),2) AS average'))
    .from('reviews')
    .rightJoin('schools', 'schools.SID', 'reviews.schoolID')
    .where('schools.schoolCountryCode', countryId)
    //.andWhere('reviews.active', '=', 1)
    .groupBy('schools.SID')
    .orderByRaw('average DESC, schools.schoolCity ASC')

In case you need data/columns:

School Table   
SID  schoolName  schoolCity  schoolCountryCode
1    ASIJ        Tokyo       JP
2    St. Mary's  Tokyo       JP

Reviews Table  
RID schoolID active  Q1  Q2  Q3 ...
1   1        1       7   8   9

1 个答案:

答案 0 :(得分:0)

我自己想通了。

我可以通过在SELECT中包含IF语句来过滤并执行ROUND / AVG,以便计算仅应用于条件。我删除了附加的andWhere active = 1,以便列出所有学校。

我使用的最终查询/ knex语句是:

SELECT Id, Name
FROM Account
WHERE Id IN (SELECT Account__c FROM A__c WHERE Status__c = 'Done')
AND Id IN (SELECT Account__c FROM B__c WHERE Status__c = 'Ready')
LIMIT 10000