我有以下表格的数据:
ID name date count
---------------------------------
1 A 1/1/2015 3
2 B 1/4/2015 2
3 C 1/6/2015 4
4 D 1/10/2015 2
我想把它变成像......
1 A 1/1/2015
1 A 1/2/2015
1 A 1/3/2015
2 B 1/4/2015
2 B 1/5/2015
3 C 1/6/2015
...
我相信这可以使用分区查询,但我在理解examples I find on the MS page时遇到了一个真正的问题。我需要在ROW_NUMBER
中使用DATEADD
,但我无法弄清楚如何让它返回正确的行数,例如第一种情况下为3。 TerritoryName
示例似乎很接近......
在最坏的情况下,我可以在VBA代码中执行此操作,并且我也知道使用填充日期的表的解决方案,但我认为这是我应该知道如何在SELECT中做的事情。
更新:我不允许更改原始数据库中的任何内容(许可问题)。我可以使用#blah,但如果可能的话,我宁愿避免这种情况。
答案 0 :(得分:2)
这是一个计数表是工作的正确工具。我保留一个作为我的系统的视图。它非常快。
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="Calc" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:7510/Calc.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://localhost:7510/Calc.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ICalc_XMLData_InputMessage">
<wsdl:part name="parameters" element="tns:XMLData"/>
</wsdl:message>
<wsdl:message name="ICalc_XMLData_OutputMessage">
<wsdl:part name="parameters" element="tns:XMLDataResponse"/>
</wsdl:message>
<wsdl:message name="ICalc_JSONData_InputMessage">
<wsdl:part name="parameters" element="tns:JSONData"/>
</wsdl:message>
<wsdl:message name="ICalc_JSONData_OutputMessage">
<wsdl:part name="parameters" element="tns:JSONDataResponse"/>
</wsdl:message>
<wsdl:portType name="ICalc">
<wsdl:operation name="XMLData">
<wsdl:input wsaw:Action="http://tempuri.org/ICalc/XMLData" message="tns:ICalc_XMLData_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/ICalc/XMLDataResponse" message="tns:ICalc_XMLData_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="JSONData">
<wsdl:input wsaw:Action="http://tempuri.org/ICalc/JSONData" message="tns:ICalc_JSONData_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/ICalc/JSONDataResponse" message="tns:ICalc_JSONData_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:service name="Calc"/>
</wsdl:definitions>
现在我们只需要一些示例数据,然后我们就可以加入我们的计数表了。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
由于您无法创建视图,因此您可以稍微调整此cte以满足您当前的需求并让cte在您的查询中。这样的事情。
set dateformat mdy --you really should use ANSI standard YYYYMMDD
insert @Something values
(1, 'A', '1/1/2015', 3)
,(2, 'B', '1/4/2015', 2)
,(3, 'C', '1/6/2015', 4)
,(4, 'D', '1/10/2015', 2)
select s.*
, DATEADD(day, t.N - 1, s.SomeDate)
from @Something s
join cteTally t on t.N <= s.SomeCount
答案 1 :(得分:1)
也许您可以使用内置的spt_values
表格,如果选择Type
=&#39; P&#39;,Number
会返回0到2047之间的连续数字。
如果列count
包含可靠的日计数值,则查询可以是:
select t.id, t.name, dateadd(d, numbers.Number, t.date) as date
from t
join master..spt_values as numbers
on numbers.Type = 'P'
and numbers.Number < t.count
答案 2 :(得分:0)
如果没有表示所有日期,并且您只想列出表格中的日期,我认为以下内容会起作用:
SELECT ranknum, itemname, itemdate
FROM (SELECT RANK() OVER(PARTITION BY t.itemdate ORDER BY allitems.itemname) ranknum
, t.id
, allitems.itemname
, t.itemdate
FROM (SELECT DISTINCT itemname FROM tablename) allitems
LEFT JOIN tablename t ON allitems.itemname = t.itemname) ranked
WHERE id IS NOT NULL
ORDER BY ranknum, itemdate