简体   繁体   English

选择具有多于一个独立列的整行

[英]Select entire row with more than one distinct column

I have a table based on invoice items where I am trying to use SQL to detect at what dates the price or currency for the combination of material/customer has changed. 我有一个基于发票项目的表格,我试图在其中使用SQL来检测物料/客户组合的价格或货币在什么日期发生了变化。 The table contains invoices for several customers although the materials can be common. 该表包含一些客户的发票,尽管材料可能很普通。

My SQL skills are quite basic and I have tried several different approaches using GROUP BY and DISTINCT that I have found in other threads but I always seem to get stuck somewhere along the way. 我的SQL技能非常基础,我尝试使用其他线程中使用的GROUP BY和DISTINCT尝试了几种不同的方法,但是我似乎总是会遇到麻烦。

This is basically what the data looks like: 数据基本上是这样的:

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

What I want to accomplish is basically to select the first row datewise for all distinct combinations of Customer/Material/Currency/Price and then subselect the entire rows (sorted by material) for those materials that occur more than once in the selection, thus indicating the price or currency has changed from the initial value. 我要完成的工作基本上是为客户/物料/货币/价格的所有不同组合按日期顺序选择第一行,然后为在选择中多次出现的那些物料再选择整个行(按物料分类)。价格或货币已从初始值更改。

The expected output from the query using the data in the table above would then look something like this: 使用上表中的数据从查询中获得的预期输出将如下所示:

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

I hope I managed to explain the problem in an understandable way. 我希望我能以一种可以理解的方式解释这个问题。 The database engine is SQL Server 2005 Express. 数据库引擎是SQL Server 2005 Express。

Any help would be appreciated... 任何帮助,将不胜感激...

The key word DISTINCT in SQL has the meaning of "unique value". SQL中的关键字DISTINCT具有“唯一值”的含义。 When applied to a column in a query it will return as many rows from the result set as there are unique, different values for that column. 当应用于查询中的列时,它将从结果集中返回与该列具有唯一,不同值的行一样多的行。 As a consequence it creates a grouped result set, and values of other columns are random unless defined by other functions (such as max, min, average, etc.) 结果,它创建了一个分组的结果集,并且其他列的值是随机的,除非由其他函数(例如,max,min,average等)定义。

If you meant to say you want to return all rows for which Col 06 has a specific value, then use the " where Col 06 = value " clause 如果要说要返回所有第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
    )

I think this is a direct translation of what you want: 我认为这是您想要的内容的直接翻译:

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;

This leaves out the currency. 这省去了货币。 Unfortunately, SQL Server doesn't support multiple arguments to distinct . 不幸的是,SQL Server不支持将多个参数用于distinct You can include it this way: 您可以这样包含它:

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;

Most databases support window/analytic functions, so you can also phrase this as: 大多数数据库都支持窗口/分析功能,因此您也可以将其表述为:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM