SQL查询,仅按一列分组

时间:2018-10-17 08:51:15

标签: sql sql-server ssrs-2012

我只想按项目对查询进行分组,因为同一项目有两个记录,但是我只想要一个。 但是,当我添加group by子句时,它要求我也添加其他列,从而使分组不起作用。

*

DECLARE @Year varchar(75) = '2018'
DECLARE @von DateTime = '1.09.2018'
DECLARE @bis DateTime = '30.09.2018'
select new_projekt ,new_geschftsartname, new_mitarbeitername, new_stundensatz
from Filterednew_projektkondition ps
left join Filterednew_fakturierungsplan fp on ps.new_projekt = fp.new_hauptprojekt1
where ps.statecodename = 'Aktiv'
  and fp.new_startdatum >= @von +'00:00:00' 
  and fp.new_enddatum <= @bis +'23:59:59'
  --and new_projekt= Filterednew_projekt.new_
--group by new_projekt

*

查看列new_projekt。第2行和第3行具有相同的项目,但我希望它仅出现一次。由于其他列不同,因此这是不可能的。 如果感兴趣,则还有另一个coluim projectcondition id,这对于两个 Result

1 个答案:

答案 0 :(得分:2)

您不能要求数据库为您任意决定,在进行分组时应该丢弃哪些记录。您必须准确而具体

例如,以下是有关某人的一些数据:

Name, AddressZipCode
John Doe, 90210
John Doe, 12345

SELECT name, addresszipcode FROM person INNER JOIN address on address.personid = person.id

为此人存储了两个地址,该人的数据在输出中重复!

  

“我不想要那个。我只想看到这个人的一行,以及他的地址”

哪个地址?

这就是你要告诉数据库的内容

  

“好吧,显然是他的当前住址”

您如何表示地址是当前地址?

  

“这是空日期为空的那个”

SELECT name, addresszipcode FROM person INNER JOIN address on address.personid = person.id WHERE address.enddate = null

如果您仍然得到两个地址,则有两个地址记录为空-您的数据违反了业务数据建模原则(“一个人的地址历史最多应具有一个当前的地址,表示为在结束日期为空之前”)-修复数据

  

“为什么我不能仅按名称分组?”

可以,但是如果这样做,您仍然必须告诉数据库如何累积显示给您的非名称数据。您需要其中的一个地址数据,它有2个要显示给您的数据,您必须告诉它要丢弃哪个。您可以这样做:

SELECT name, MAX(addresszipcode) FROM person INNER JOIN address on address.personid = person.id GROUP BY name

  

“但是我不想要最大的邮政编码?那没有道理”

好的,请使用MIN,SUM,AVG,以及所有有意义的内容。如果这些都不有意义,则使用可行的方法,例如结束日期最高的地址行,或将来结束日期最低的地址行。如果您只想在节目中显示一个地址,则必须决定如何将数据简化为一条记录-您必须编写规则以使数据库遵循该规则,并且对此毫无疑问您必须创建一条规则 >因此,将其作为描述您实际需要的规则


好吧,所以您创建了一条规则-您只需要new_stundenstatz最小的行

DECLARE @Year varchar(75) = '2018'
DECLARE @von DateTime = '1.09.2018'
DECLARE @bis DateTime = '30.09.2018'
select new_projekt ,new_geschftsartname, new_mitarbeitername, new_stundensatz
from 

(SELECT *, ROW_NUMBER() OVER(PARTITON BY new_projekt ORDER BY new_stundensatz) rown FROM Filterednew_projektkondition) ps

left join 
Filterednew_fakturierungsplan fp on ps.new_projekt = fp.new_hauptprojekt1 
where ps.statecodename = 'Aktiv'
  and fp.new_startdatum >= @von +'00:00:00' 
  and fp.new_enddatum <= @bis +'23:59:59'
  and ps.rown = 1

在这里,我已使用分析操作对PS表中的行进行编号。它们以从1开始的new_stundensatz升序编号。new_projekt更改时,编号重新开始,因此每个new_projekt都将有一个数字1行。条件

(在将来应用此技术的有用提示。如果是要向其添加行号的FP表,我们需要将AND fp.rown= 1放在ON子句中,而不是WHERE子句中,因为将其放在将使LEFT联接表现得像INNER的位置,隐藏没有任何FP匹配记录的行)