按问题分组的普遍查询
pervasive query with group by issue
我正在尝试 运行 在普适数据库上进行此查询
select cust_no,cust_name,sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null and number is not null and bvtotal > 1000 and in_date < 20140101
group by cust_no,cust_name
order by sum(bvtotal) desc;
如何在子结果中排除 in_date > 20140101 的组结果?
我的这个查询也在获取 in_date > 20140101
的结果
我是不是做错了什么?
我得到的示例输出是这种格式
cust_no cust_name amount
A a1 500
B b1 500
C c1 1000
我想用 cust_no 排除这条记录 'A' 因为它在 20140202
与 in_date 有过交易
在我的原始数据中考虑我有像
这样的记录
cust_no cust_name amount in_date
A a1 100 20130203
A a1 400 20130101
A a1 1000 20140503
我认为您需要将日期常量指定为日期,除非您真的想处理整数。
select cust_no,cust_name,sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null and number is not null and bvtotal > 1000 and in_date < '2014-01-01'
group by cust_no,cust_name
order by sum(bvtotal) desc;
我不明白你到底需要什么,
但您似乎混合了 INT 和 DATE 类型。
因此,如果您的 in_date
字段的类型为 DATE
select
cust_no,
cust_name,
sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null
and number is not null
and bvtotal > 1000
and in_date < DATE('2014-01-01')
group by cust_no,cust_name
order by sum(bvtotal) desc;
如果您的 in_date
字段的类型为 TIMESTAMP
select
cust_no,
cust_name,
sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null
and number is not null
and bvtotal > 1000
and in_date < TIMESTAMP('2014-01-01 00:00:00')
group by cust_no,cust_name
order by sum(bvtotal) desc;
您需要根据一组 ID 排除所有记录。通常,您使用子查询执行此操作:
SELECT cust_no,
cust_name,
sum(bvtotal) AS Amount
FROM sales_history_header
WHERE cust_no IS NOT NULL
AND number IS NOT NULL
AND bvtotal > 1000
AND cust_no NOT IN (
SELECT cust_no
FROM sales_history_header
WHERE in_date >= 20140101
AND cust_no IS NOT NULL
)
GROUP BY cust_no,
cust_name
ORDER BY sum(bvtotal) DESC;
子查询的 AND cust_no IS NOT NULL
部分是为了避免 NOT IN
和 NULL
值出现问题。如果将其重写为 NOT EXISTS
相关子查询,您可能会有更好的性能,但根据我的经验,MySQL 在这些方面非常糟糕。
另一种选择是更明确的自反加入方法(LEFT JOIN 和 filter where right table is null)但这有点……粗略的感觉?……因为你看起来允许 cust_no
成为 NULL
并且因为它是一个聚合查询所以感觉你必须担心乘法行:
SELECT s1.cust_no,
s1.cust_name,
sum(s1.bvtotal) AS Amount
FROM sales_history_header s1
LEFT JOIN (
SELECT cust_no
FROM sales_history_header
WHERE cust_no IS NOT NULL
AND number IS NOT NULL
AND bvtotal > 1000
AND in_date >= 20140101) s2
ON s2.cust_no = s1.cust_no
WHERE s1.cust_no IS NOT NULL
AND s1.number IS NOT NULL
AND s1.bvtotal > 1000
AND s2.cust_no IS NULL
GROUP BY cust_no,
cust_name
ORDER BY sum(bvtotal) DESC;
LEFT JOIN
结合WHERE [...] s2.cust_no IS NULL
是去掉不需要的记录的部分。
我正在尝试 运行 在普适数据库上进行此查询
select cust_no,cust_name,sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null and number is not null and bvtotal > 1000 and in_date < 20140101
group by cust_no,cust_name
order by sum(bvtotal) desc;
如何在子结果中排除 in_date > 20140101 的组结果?
我的这个查询也在获取 in_date > 20140101
的结果我是不是做错了什么?
我得到的示例输出是这种格式
cust_no cust_name amount
A a1 500
B b1 500
C c1 1000
我想用 cust_no 排除这条记录 'A' 因为它在 20140202
与 in_date 有过交易在我的原始数据中考虑我有像
这样的记录cust_no cust_name amount in_date
A a1 100 20130203
A a1 400 20130101
A a1 1000 20140503
我认为您需要将日期常量指定为日期,除非您真的想处理整数。
select cust_no,cust_name,sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null and number is not null and bvtotal > 1000 and in_date < '2014-01-01'
group by cust_no,cust_name
order by sum(bvtotal) desc;
我不明白你到底需要什么,
但您似乎混合了 INT 和 DATE 类型。
因此,如果您的 in_date
字段的类型为 DATE
select
cust_no,
cust_name,
sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null
and number is not null
and bvtotal > 1000
and in_date < DATE('2014-01-01')
group by cust_no,cust_name
order by sum(bvtotal) desc;
如果您的 in_date
字段的类型为 TIMESTAMP
select
cust_no,
cust_name,
sum(bvtotal) as Amount
from sales_history_header
where cust_no is not null
and number is not null
and bvtotal > 1000
and in_date < TIMESTAMP('2014-01-01 00:00:00')
group by cust_no,cust_name
order by sum(bvtotal) desc;
您需要根据一组 ID 排除所有记录。通常,您使用子查询执行此操作:
SELECT cust_no,
cust_name,
sum(bvtotal) AS Amount
FROM sales_history_header
WHERE cust_no IS NOT NULL
AND number IS NOT NULL
AND bvtotal > 1000
AND cust_no NOT IN (
SELECT cust_no
FROM sales_history_header
WHERE in_date >= 20140101
AND cust_no IS NOT NULL
)
GROUP BY cust_no,
cust_name
ORDER BY sum(bvtotal) DESC;
子查询的 AND cust_no IS NOT NULL
部分是为了避免 NOT IN
和 NULL
值出现问题。如果将其重写为 NOT EXISTS
相关子查询,您可能会有更好的性能,但根据我的经验,MySQL 在这些方面非常糟糕。
另一种选择是更明确的自反加入方法(LEFT JOIN 和 filter where right table is null)但这有点……粗略的感觉?……因为你看起来允许 cust_no
成为 NULL
并且因为它是一个聚合查询所以感觉你必须担心乘法行:
SELECT s1.cust_no,
s1.cust_name,
sum(s1.bvtotal) AS Amount
FROM sales_history_header s1
LEFT JOIN (
SELECT cust_no
FROM sales_history_header
WHERE cust_no IS NOT NULL
AND number IS NOT NULL
AND bvtotal > 1000
AND in_date >= 20140101) s2
ON s2.cust_no = s1.cust_no
WHERE s1.cust_no IS NOT NULL
AND s1.number IS NOT NULL
AND s1.bvtotal > 1000
AND s2.cust_no IS NULL
GROUP BY cust_no,
cust_name
ORDER BY sum(bvtotal) DESC;
LEFT JOIN
结合WHERE [...] s2.cust_no IS NULL
是去掉不需要的记录的部分。