首页 > 解决方案 > SQL-过滤器的多个子句

问题描述

所以我不完全确定它应该是 WHERE 语句还是子条款,还是 CASE。坦率地说,我仍在尝试学习 subclause 和 CASE 的用例。

最后我想要的是他们的出席人数和他们在特定时间范围内支付的发票总和。

尝试“错误:在“来自”位置或附近的语法错误:349 时出现错误

预期输出:孩子姓名、中心 ID、教室名称、出勤人数、发票总和、日期、

我要加入多个表格,并希望过滤特定日期内的出勤和特定日期内支付的发票:

select accounts.fname as first_name, accounts.lname as last_name, accounts.dob, centers.label, classrooms.label as classroom_label, 
count(*) as no_of_days_attended, sum(transactions.amount / 100.0) as sum_of_transactions_paid, 
from daily_reports
join account_classrooms
on daily_reports.account_classroom_id = account_classrooms.id
join accounts
on account_classrooms.account_id = accounts.id
join classrooms
on account_classrooms.classroom_id = classrooms.id
join centers
on classrooms.center_id = centers.id
join invoices
on centers.id = invoices.center_id
join transactions
on transactions.invoice_id = invoices.id
where daily_reports.ref_date and transactions.created_at > {{start_date}} and daily_reports.ref_date and transactions.created_at < {{end_date}} and centers.id = {{center_id}}
group by daily_reports.account_classroom_id, accounts.id, classrooms.id, centers.id, 

太感谢了!

标签: sqlcasewhere-clause

解决方案


你有几个问题正在发生。

首先,在 FROM 子句之前有一个额外的逗号,在 GROUP BY 的末尾还有一个逗号。您的 GROUP BY 列不会出现在您的 SELECT 语句中,因此这不起作用。在进行聚合(SUM()、MAX() 等)时,引擎必须知道按哪些列对聚合进行分组。这些是您的 SELECT 列表中的列。

其次,您不能像这样一次评估两列:

daily_reports.ref_date and transactions.created_at > {{start_date}}

如果你这样做了,你会得到这个错误:

An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.

每个评估都必须是原子的。在这个例子中,它必须是这样的:

daily_reports.ref_date > {{start_date}} and transactions.created_at > {{start_date}}

但是,可以使用 BETWEEN 运算符进一步清理 WHERE 子句。此外,最好不要使用隐式 JOIN。在代码中定义 JOIN 的类型(例如 INNER JOIN)。

我已经应用了别名,格式化了代码并应用了 BETWEEN 运算符。看看这是否适合你。如您所见,当代码格式正确时,它更具可读性,并且更容易发现问题。

SELECT  a.fname AS first_name
        ,a.lname AS last_name
        ,a.dob
        ,cn.label
        ,cl.label AS classroom_label
        ,COUNT(*) AS no_of_days_attended
        ,SUM(t.amount / 100.0) AS sum_of_transactions_paid
FROM    daily_reports AS dr
        INNER JOIN account_classrooms AS ac ON dr.account_classroom_id = ac.id
        INNER JOIN accounts AS a ON ac.account_id = a.id
        INNER JOIN classrooms AS cl ON ac.classroom_id = cl.id
        INNER JOIN centers AS cn ON cl.center_id = cn.id
        INNER JOIN invoices AS i ON cn.id = i.center_id
        INNER JOIN transactions AS t ON t.invoice_id = i.invoices.id
WHERE   dr.ref_date BETWEEN @start_date AND @end_date
        AND t.created_at BETWEEN @start_date AND @end_date
        AND cn.id = @center_id
GROUP BY
        a.fname
        ,a.lname
        ,a.dob
        ,cn.label

推荐阅读