Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从同一列检索两组不同的条件数据?_Sql_Sql Server - Fatal编程技术网

Sql 如何从同一列检索两组不同的条件数据?

Sql 如何从同一列检索两组不同的条件数据?,sql,sql-server,Sql,Sql Server,成功标准: 检索2006年之后开始的员工 对于进行销售的员工,请提供从开始日期到销售日期的天数 对于没有销售的员工,请提供从开始日期到当前日期的天数,并强调到目前为止没有销售 注意,在实际数据集中,每个员工都有多个销售额,这就是我使用 总最小值 到目前为止,我的代码: SELECT People.Employee MIN(DATEDIFF(DAY,Dates.Startdate,Dates.Salesdate)) as 'Days to First Sale' FRO

成功标准:

  • 检索2006年之后开始的员工
  • 对于进行销售的员工,请提供从开始日期到销售日期的天数
  • 对于没有销售的员工,请提供从开始日期到当前日期的天数,并强调到目前为止没有销售
注意,在实际数据集中,每个员工都有多个销售额,这就是我使用 总最小值

到目前为止,我的代码:

SELECT
    People.Employee
    MIN(DATEDIFF(DAY,Dates.Startdate,Dates.Salesdate)) as 'Days to First Sale'    
FROM People
LEFT JOIN Dates ON People.ID = Dates.ID
    AND YEAR(CASE WHEN Dates.SalesDate > Dates.DeliveryDate THEN Dates.SalesDate ELSE 
    Sales.DeliveryDate END) > (2006)
当前代码输出:

雇员 距首次销售日 布兰迪 33 做记号 18 请尝试以下专栏:

CAST(DATEDIFF(dd, Dates.StartDate, COALESCE(Dates.SalesDate,CURRENT_TIMESTAMP)) as VARCHAR) +
case when Dates.salesdate is null then ' no sales' else '' end

您可以使用
cte
分隔逻辑,然后简单地联接以获得相应的名称

with d as (
    select id, Concat(Min(DateDiff(day,Startdate,IsNull(Salesdate,GetDate()))), Iif(Min(salesdate) is null,' Days with no sale','')) Sales
    from dates
    where startdate>'20060101'
    group by Id
)
select p.Employee, d.sales [Days to First Sale]
from d
join people p on p.Id=d.Id

由于您总是希望从Dates表中获取StartDate,而不管sales date列的状态如何,因此需要简化联接。在使用sales date列的联接上添加一些偶然逻辑,意味着您正在阻止返回所有日期

您可以将带有更复杂逻辑的case语句放入select中,因为这不会阻止任何行的存在。此外,如果您还想输出字符串,则需要将DATEFDIFF的整数结果转换为varchar。您还需要包含一个group by,您不能只要求一个min(),而不说明聚合依据

另一个问题是为什么会有左连接?看起来似乎Dates表中每个员工至少应该有一行起始日期-如果没有,那么您就没有可靠的方法按起始日期筛选员工,否则左联接就有点多余了

我会这样做:

SELECT p.ID,
p.Employee ,
case when min(Dates.Salesdate) IS NOT NULL then 
  cast (DATEDIFF(DAY,min(Dates.Startdate),min(Dates.Salesdate)) as varchar(50))
  else 
  cast (DATEDIFF(DAY,min(Dates.Startdate),getdate()) as varchar(50)) + ' days without sale' 
end as 'Days to First Sale'    
FROM People p
LEFT JOIN Dates d ON p.ID = d.ID
and datepart(year,d.StartDate) >= 2006
group by p.Id, p.Employee

数据建模提示-我将创建一个单独的列来标记没有销售的员工,并且在距首次销售的天数中只包含整数-否则,通过混合整数和字符串,您将无法对“距首次销售的天数”列进行任何计算。

该代码的作用是什么,为什么错误或不足?i、 e.显示当前输出并解释其不符合要求的原因。为什么使用aggregate min()?在日期表中每个员工有多行吗?是的,在实际数据集中,根据日期表中的销售数量,每个员工有多行…感谢您的努力Alex,但是“dd”代表什么?对于通过dd的天数、分钟数mi等的差异。我可能做了一些错误的事情,但这实际上是在返回给我答案“首次销售天数”和“未销售天数”“合并在一列中而无法区分它们左连接是因为在实际数据集中,一名员工可以有多个销售日期,因此可以有多个销售日期,但开始日期和ID将保持不变。在所需的结果表中,您表明希望将这两个日期都放在一列中。else子句将短语“days without sale”添加到您指定的整数值中。我现在没有登录到sql server进行检查,可能会将第二个cast语句更改为cast as varchar(10)而不是50。左连接没有执行您认为的操作。如果您有一对多关系,那么在两个表之间进行内部联接将为“多”表(即日期表)中的每条记录返回一行。只有在dates表中可能没有匹配行的情况下,左连接才有意义,但如果是这样,您也无法检索开始日期。谢谢,我找到了它!