我有一个基于发票项目的表格,我试图使用SQL来检测物料/客户组合的价格或货币在哪些日期发生变化。该表包含多个客户的发票,尽管这些材料可能很常见。
我的SQL技能非常基础,我尝试了几种不同的方法,使用了我在其他线程中找到的GROUP BY和DISTINCT,但我似乎总是被困在某个地方。
这基本上就是数据的样子:
Invoice Inv. Date Material Price Currency Per/Qty Customer
SE100 20140901 111111 1 EUR 1 840006
SE100 20140901 222222 2 EUR 1000 840006
SE100 20140901 333333 3 USD 1 840006
SE101 20140902 111111 1 EUR 1 840006
SE101 20140902 222222 2 EUR 1000 840006
SE101 20140902 333333 3 USD 1 840006
SE102 20140903 111111 2 EUR 1 840006
SE102 20140903 222222 2 USD 1000 840006
SE102 20140903 333333 3 USD 1 840006
SE103 20140904 111111 1 EUR 1 840006
SE103 20140904 222222 2 USD 1000 840006
SE103 20140904 333333 3 USD 1 840006
我想要完成的基本上是为客户/物料/货币/价格的所有不同组合选择日期的第一行,然后为选择中出现多次的那些物料选择整个行(按材料排序) ,从而表明价格或货币已从初始值发生变化。
使用上表中的数据查询的预期输出将如下所示:
Invoice Inv. Date Material Price Currency Per/Qty Customer
SE100 20140901 111111 1 EUR 1 840006
SE102 20140903 111111 2 EUR 1 840006
SE103 20140904 111111 1 EUR 1 840006
SE100 20140901 222222 2 EUR 1000 840006
SE102 20140903 222222 2 USD 1000 840006
我希望我能以一种可以理解的方式解释这个问题。数据库引擎是SQL Server 2005 Express。
任何帮助将不胜感激......
答案 0 :(得分:0)
SQL中的关键字DISTINCT
具有"唯一值"的含义。当应用于查询中的列时,它将从结果集中返回尽可能多的行,因为该列具有唯一的不同值。因此,它创建了一个分组结果集,其他列的值是随机的,除非由其他函数定义(例如max,min,average等)。
如果您想要返回Col 06具有特定值的所有行,请使用" where Col 06 = value
"条款
SELECT mt.*
FROM (
SELECT DISTINCT col6
FROM mytable
) mto
JOIN mytable mt
ON mt.id =
(
SELECT TOP 1 id
FROM mytable mti
WHERE mti.col6 = mto.col6
-- ORDER BY
-- id
-- Uncomment the lines above if the order matters
)
答案 1 :(得分:0)
我认为这是你想要的直接翻译:
select t.*
from mydata t join
(select Customer, Material, count(distinct price) as numprices
from mydata
group by Customer, Material
having count(distinct price) > 1
) cmcp
on t.customer = cmcp.customer and t.material = cmcp.material;
这就省去了货币。不幸的是,SQL Server不支持distinct
的多个参数。您可以这样包含它:
select t.*
from mydata t join
(select Customer, Material,
count(distinct cast(price as varchar(255)) + ':' + currency) as numprices
from mydata
group by Customer, Material
having count(distinct cast(price as varchar(255)) + ':' + currency) > 1
) cmcp
on t.customer = cmcp.customer and t.material = cmcp.material;
大多数数据库都支持窗口/分析函数,因此您也可以将其标记为:
select t.*
from (select t.*,
min(cast(price as varchar(255)) + ':' + currency)) over (partition by Customer, Material) as minprice,
max(cast(price as varchar(255)) + ':' + currency)) over (partition by Customer, Material) as maxprice
from mydata t
) t
where minprice <> maxprice
order by Material, Inv_Date;