我正在使用sqlc库从 SQL 查询生成 go 代码。
我有一个像这样的子查询的查询:
COALESCE(SUM(invoice_payments.total), 0) AS paid,
并sqlc generate
返回以下错误:
# package db
query.sql:101:1: relation "bigint" does not exist
我尝试使用 , 等进行操作::numeric
,::int
并且总是收到相同的结果
也试图像这样投长:
CAST(SUM(CAST( invoice_payments.total AS LONG)) AS LONG) AS paid,
SUM(invoice_payments.total::long)::long AS paid,
结果相同
带有完整示例的游乐场
下面的完整示例
CREATE TABLE clients (
id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
account_id text NOT NULL,
CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
"name" text NOT NULL,
archived boolean NOT NULL DEFAULT FALSE,
-- UNIQUE (account_id, name), // what about typos etc balls
email text NOT NULL,
phone text NOT NULL DEFAULT '',
-- UNIQUE (account_id, email),
-- address
address_1 text NOT NULL DEFAULT '',
address_2 text NOT NULL DEFAULT '',
city text NOT NULL DEFAULT '',
state_region text NOT NULL DEFAULT '',
postal_code text NOT NULL DEFAULT '',
country text NOT NULL DEFAULT '',
-- currency_code text NOT NULL DEFAULT 'USD',
-- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code) ON DELETE RESTRICT,
-- language_code text NOT NULL,
-- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
created_at timestamp NOT NULL DEFAULT now(),
updated_at timestamp NOT NULL DEFAULT now(),
archived_at timestamp
);
CREATE TABLE invoices (
-- why do we generate the invoice id on the server?
id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
account_id text NOT NULL,
CONSTRAINT fk_account FOREIGN KEY (account_id) REFERENCES accounts (id) ON DELETE CASCADE ON UPDATE CASCADE,
client_id uuid NOT NULL,
CONSTRAINT fk_client FOREIGN KEY (client_id) REFERENCES clients (id) ON DELETE CASCADE,
status text NOT NULL DEFAULT 'draft',
CONSTRAINT fk_status FOREIGN KEY (status) REFERENCES invoice_statuses (status) ON DELETE RESTRICT,
archived boolean NOT NULL DEFAULT FALSE,
heading text NOT NULL DEFAULT 'Invoice',
NUMBER text NOT NULL,
UNIQUE (account_id, NUMBER),
REFERENCE text NOT NULL DEFAULT '',
issued date NOT NULL,
due date NOT NULL,
color text NOT NULL CHECK (LENGTH(color) = 7),
-- currency_code text NOT NULL DEFAULT 'USD',
-- CONSTRAINT fk_currency FOREIGN KEY (currency_code) REFERENCES currencies_iso_4217 (code),
-- language_code text NOT NULL,
-- CONSTRAINT fk_language FOREIGN KEY (language_code) REFERENCES languages_iso_639_1 (code) ON DELETE RESTRICT,
-- items is a list of name, details, price, taxes
items jsonb NOT NULL DEFAULT '[]' ::jsonb,
pre_tax_discounts jsonb NOT NULL DEFAULT '[]' ::jsonb,
-- taxes is a list of name, rate, business number
taxes jsonb NOT NULL DEFAULT '[]' ::jsonb,
-- discounts is a list of name, type (rate/fixed), application (pre/post tax), value
post_tax_discounts jsonb NOT NULL DEFAULT '[]' ::jsonb,
-- deposits is a list of of name, type (rate/fixed), value
deposits jsonb NOT NULL DEFAULT '[]' ::jsonb,
---- CALCULATED VALUES ---
-- subtotal is pre-tax, pre-discount
subtotal numeric NOT NULL DEFAULT 0,
pre_tax_total numeric NOT NULL DEFAULT 0,
post_tax_total numeric NOT NULL DEFAULT 0,
-- INCLUDES pre_tax_total
grand_total numeric NOT NULL DEFAULT 0,
deposit_total numeric NOT NULL DEFAULT 0,
-- current payment total (TODO think about if this is necessary)
payment numeric NOT NULL DEFAULT 0,
-- total of deposits - payments OR total - payments
-- NOTE if an invoice has deposits, then it is a bit of a different creature
-- or should we call it amount due?
deposit_due numeric NOT NULL DEFAULT 0,
balance numeric NOT NULL DEFAULT 0,
---- NOTES/TERMS
notes text NOT NULL DEFAULT '',
terms text NOT NULL DEFAULT '',
---- TIMING ----
last_sent_at timestamp,
last_viewed_at timestamp,
last_paid_at timestamp,
last_refunded_at timestamp,
last_deleted_at timestamp,
archived_at timestamp,
created_at timestamp NOT NULL DEFAULT now(),
updated_at timestamp NOT NULL DEFAULT now()
);
CREATE TABLE invoice_payments (
id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
invoice_id uuid NOT NULL,
CONSTRAINT fk_invoice FOREIGN KEY (invoice_id) REFERENCES invoices (id) ON DELETE CASCADE,
total numeric NOT NULL,
DATE date NOT NULL,
method text NOT NULL,
CONSTRAINT fk_method FOREIGN KEY (method) REFERENCES payment_methods (method) ON DELETE CASCADE,
notes text NOT NULL DEFAULT '',
created_at timestamp NOT NULL DEFAULT now(),
updated_at timestamp NOT NULL DEFAULT now()
);
---- CLIENTS ----
-- name: SearchClients :many
SELECT
clients.id,
-- contact
clients.name,
clients.email,
clients.phone,
-- address
clients.address_1,
clients.address_2,
clients.city,
clients.state_region,
clients.postal_code,
clients.country,
-- management
clients.archived,
COUNT(invoices.id) AS number_invoices,
(COALESCE(SUM(invoices.grand_total), 0))::numeric AS owes,
(COALESCE(SUM(invoices.paid), 0))::numeric AS paid
FROM
clients
LEFT JOIN (
SELECT
invoices.id,
invoices.client_id,
invoices.number,
invoices.issued,
invoices.due,
invoices.status,
invoices.grand_total,
-- replacing the paid field definition with this comment works ok
--0 AS paid,
COALESCE(SUM(invoice_payments.total), 0) AS paid,
-- replacing the overdue field definition with this comment works ok
0 as overdue
--CASE WHEN due < CURRENT_DATE THEN
-- invoices.grand_total - COALESCE(SUM(invoice_payments.total), 0)
--ELSE
-- 0
--END AS overdue
FROM
invoices
LEFT JOIN invoice_payments ON invoices.id = invoice_payments.invoice_id
GROUP BY
invoices.id) AS invoices ON clients.id = invoices.client_id
WHERE
clients.account_id = @account_id
AND clients.archived = ANY (@archived::boolean[])
AND (clients.name ILIKE '%' || @query || '%'
OR invoices.number ILIKE '%' || @query || '%')
GROUP BY
clients.id
ORDER BY
clients.name ASC,
clients.updated_at DESC;