我有一个关于SQL的问题,老实说我在尝试之前尝试搜索方法。我将在下面给出一个抽象(但精确)的描述,并将非常感谢您的解决方案示例(SQL查询)。
我有什么:
表A包含项目的类别ID ,每个项目的价格(以美元为单位)。 类别ID 具有 int 类型的值,价格是字符串,看起来像" USD 200000000&#34 ; (实际值乘以10 ^ 7)。表格还有种列,其中 int 类型的值。
表B与类别ID 和名称的关系。
我需要什么:
获取价格diapasons(如0-100 | 100-200 | ...)作为列名称的表格,并计算每个类别ID (作为行名称)的项目数量价格diapasons。所有结果必须通过种类参数(来自表A)进行过滤,其值为 3 。
我遇到的问题(以及导致询问SQL查询示例的问题):
感谢回应,无知将被理解。
答案 0 :(得分:1)
如果您只需要类别ID,则不需要B
。您正在寻找的是条件聚合,例如:
select category_id,
sum(case when cast(substring(price, 4, 100) as int)/10000000 < 100 then 1 else 0 end) as price_000_100
sum(case when cast(substring(price, 4, 100) as int)/10000000 >= 100 and cast(substring(price, 4, 100) as int)/10000000 < 200
then 1 else 0
end) as price_100_200,
. . .
from a
group by category_id
答案 1 :(得分:1)
没有标准的方法来做你所描述的。
那是因为做(3)你需要一个虚拟对象交叉表,而这不是ANSI SQL。每个DBMS都有自己的实现。另外,数据透视表中的动态列是一个额外的复杂功能。
例如,Postgres称之为&#34;交叉号&#34;并要求安装tablefunc模块。见SO question和documentation。与使用PIVOT command。
的SQL Server进行比较您可以使用合理标准的SQL来接近。
以下是基于SQLite的示例。一点点的转换将为其他系统提供解决方案,例如在postgre中SUBSTR
substring(string [from int] [for int])
。
假设格式为数据表:
和类别名称表:
然后以下代码将产生:
WITH dataCTE AS
(SELECT product_id AS 'ID', CAST(SUBSTR(price, 5) AS INT)/1000000 AS 'USD',
CASE WHEN (CAST(SUBSTR(price, 5) AS INT)/1000000) <= 500 THEN
100 ELSE 200
END AS 'Interval'
FROM data
WHERE kind = 3),
groupCTE AS
(SELECT dataCTE.ID AS 'ID', dataCTE.USD AS 'USD', dataCTE.Interval AS 'Interval',
CASE WHEN dataCTE.Interval = 100 THEN
CAST(dataCTE.USD AS INT)/100
ELSE
(CAST(dataCTE.USD-500 AS INT)/200)+5
END AS 'GroupID'
FROM dataCTE),
cleanCTE AS
(SELECT *, CASE WHEN groupCTE.Interval = 100 THEN
CAST(groupCTE.GroupID *100 AS VARCHAR)
|| '-' ||
CAST((groupCTE.GroupID *100)+99 AS VARCHAR)
ELSE
CAST(((groupCTE.GroupID-5)*200)+500 AS VARCHAR)
|| '-' ||
CAST(((groupCTE.GroupID-5)*200)+500+199 AS VARCHAR)
END AS 'diapason'
FROM groupCTE
INNER JOIN cat_name AS cn ON groupCTE.ID = cn.cat_id)
SELECT *
FROM cleanCTE;
如果您将最后SELECT
修改为:
SELECT name, diapason, COUNT(diapason)
FROM cleanCTE
GROUP BY name, diapason;
然后你得到一个分组输出:
在没有指定确切系统的情况下,这将尽可能接近;即使这样,你也会遇到动态创建列名的问题。