好的,这是问题,我有5个不同的表由上帝知道谁知道每个人有不同的数据,dI需要将它们合并在一个表中。
我的第一个问题是每天都有时间戳但我只需要每天添加最后一条记录,那么如何每天搜索最后的记录并将它们保存在新表中,这些表大部分都很大大约4亿条记录。
以下查询返回最后一个注册表,但我需要搜索每一天,最后一个注册表(因为有人搞乱了这个工作,并且每天15分钟就做了很多重复数据)。
日期范围从2006年1月1日到当天(取决于表格),有些日子一直持续到2008年。
到目前为止,我有这个。
SELECT * FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
WHERE dExD_Fecha = (SELECT MAX(dExD_Fecha)
FROM dbo.Existencia_WH_PRISM_BACKUP)
这给我带来了像
这样的结果NombreEntidad dExD_Fecha LDWHSE LDLOCN LDRESC LDLOTN LDGRDE LDLOCQ LDUMSR LDRSCL LDRSSC LDQRUM LDRCUM LDPOTF LDREVL LDCLCD LDOOIN LDAVPL LDOHIN LDDVIN LDDWIP LDQYRM LDQYRS LDDLRC LDTLRC LDTRAN LDFIFO LDETD LDETT LDEXPD LDVNNO LDPOSQ LDDTMT LDACTP LDZONE LDAVPT LDRTND LDCDDT LDLSQY LDAGE1 LDAGE2 LDAGE3 LDAGE4 LDAGE5 LDAMIR LDRCLS LDPTAW LDCSPK LDQYOU LDBLNK
HDZALM 2010-05-28 12:01:00.000 1T A04 405120 K0146 864.000000 CJ PT 40 864.000000 CJ 0.000000 STOC N 2 Y Y N 0.000000 0.000000 1100527 75934 6659304 1100527 1100527 61504 1110527 5 1100527 N A Y 0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000
HDZALM 2010-05-28 12:01:00.000 1T A04 405120 K0147 1944.000000 CJ PT 40 1944.000000 CJ 0.000000 STOC N 2 Y Y N 0.000000 0.000000 1100527 120112 6665777 1100527 1100527 120051 1110527 5 1100527 N A Y 0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000
HDZALM 2010-05-28 12:01:00.000 1T A05 405120 K0146 2052.000000 CJ PT 40 2052.000000 CJ 0.000000 STOC N 2 Y Y N 0.000000 0.000000 1100527 54402 6658261 1100527 1100527 54146 1110527 5 1100527 N A Y 0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000
HDZALM 2010-05-28 12:01:00.000 1T A05 405120 K0147 2160.000000 CJ PT 40 2160.000000 CJ 0.000000 STOC N 2 Y Y N 0.000000 0.000000 1100527 153911 6671885 1100527 1100527 153714 1110527 5 1100527 N A Y 0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000
HDZALM 2010-05-28 12:01:00.000 1T A06 405120 K0146 4212.000000 CJ PT 40 4212.000000 CJ 0.000000 STOC N 2 Y Y N 0.000000 0.000000 1100527 43743 6657177 1100527 1100527 43625 1110527 5 1100526 N A Y 0.000000 9999999 9999999 9999999 9999999 9999999 N Y Y N 0.000000
答案 0 :(得分:2)
您没有提到SQL Server的版本(也没有关于您当前如何执行此操作的详细信息),但是如果它是SQL Server 2005+,您可以:
With NumberedData As
(
Select ...
, Row_Number() Over ( Partition By DateDiff(d, 0, E.dExD_Fetcha)
Order By E.dExD_Fetcha Desc ) As Num
From PDFP.dbo.[Existencia_WH_PRISM_BACKUP] As E
)
Select ...
From Data
Where Num = 1
答案 1 :(得分:0)
我喜欢Thomas发布的解决方案,因为无需使用游标的查询几乎总是优于使用游标的查询。 (SQL是为SET逻辑构建的,所以它总能更有效地做它最擅长的事情。)
您还说过,只要它们全部存储在同一时间,您就需要每天获得多行。托马斯解决方案中写的CTE表达式只为您提供了最后一个表达式。否则你可以轻松修改他的解决方案。
下面是一个游标解决方案,因为你对它们有好奇心。我提供的建议是你不应该使用它,但你应该知道它是可能的。
如果您想保留结果以供以后分析,您当然会使用真实表而不是表变量。
DECLARE @t1 TABLE ( DtTm datetime )
DECLARE @Dt datetime
DECLARE c CURSOR FOR
SELECT CONVERT(datetime, CONVERT(char(11), dExD_Fecha, 113))
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
GROUP BY CONVERT(char(11), dExD_Fecha, 113)
OPEN c
FETCH NEXT FROM c INTO @Dt
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @t1
SELECT dExD_Fecha -- add any other fields you care to capture here and above to the table definition
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
WHERE dExD_Fecha = (
SELECT MAX(dExD_Fecha)
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
WHERE CONVERT(datetime,CONVERT(char(11), dExD_Fecha, 113)) = @Dt)
FETCH NEXT FROM c INTO @Dt
END
CLOSE c
DEALLOCATE c
SELECT * FROM @t1
答案 2 :(得分:0)
试试这个:
SELECT e.*
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] e
INNER JOIN (
SELECT MAX(dExd_Fecha) AS dExd_Fecha_Max
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0)
) m
ON e.dExD_Fecha = m.dExd_Fecha_Max
ORDER BY e.dEXd_Fecha
这里的想法是创建一个按日分组的最大日期的子查询,然后加入主表。
如果要识别超出该范围的值以便删除它们,可以对该集合执行左外连接:
/** DELETE FROM x **/
SELECT *
FROM (
SELECT
dExd_Fecha,
YEAR(dExd_Fecha) AS dExd_Ano,
MONTH(dExd_Fecha) AS dExd_Semana,
NTILE(10) OVER (ORDER BY dExd_Fecha) AS dExd_Groupo
FROM [Existencia_WH_PRISM_BACKUP]
) x
LEFT OUTER JOIN (
SELECT MAX(dExd_Fecha) AS dExd_Fecha_Max
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0)
) y
ON x.dExd_Fecha = y.dExd_Fecha_Max
WHERE
x.dExd_Ano = 2010
AND x.dExd_Semana = 1
AND y.dExd_Fecha_Max IS NULL
ORDER BY x.dExd_Fecha
此SELECT语句使用子查询中的YEAR和MONTH值来执行批处理方法并以较小的数量选择/删除记录。
原始答案如下:
SELECT e.*
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP] e
INNER JOIN (
SELECT
MAX(dExd_Fecha) AS dExd_Fecha_Max,
/** get the year of the last date **/
YEAR(MAX(DATEADD(YY, DATEDIFF(YY, 0, dExd_Fecha), 0))) AS dExd_Ano_Max,
/** get the month of the last date **/
MONTH(MAX(DATEADD(MM, DATEDIFF(MM, 0, dExd_Fecha), 0))) AS dExd_Mes_Max,
/** get the week of the last date **/
DATEPART(WEEK, MAX(dExd_Fecha)) AS dExd_Semana_Max,
/** set a number to divide the total rows into ten groups **/
NTILE(10) OVER (ORDER BY MAX(dExd_Fecha)) AS dExd_Groupo
FROM [PDP].[dbo].[Existencia_WH_PRISM_BACKUP]
GROUP BY DATEADD(DD, DATEDIFF(DD, 0, dExd_Fecha), 0)
) m
ON e.dExD_Fecha = m.dExd_Fecha_Max
WHERE
m.dExd_Ano_Max = 2010
AND m.dExd_Mes_Max = 1