从 SQL Servertable 中的分区中检索数据
Posted
技术标签:
【中文标题】从 SQL Servertable 中的分区中检索数据【英文标题】:Retrieve a data from a partition in SQL Servertable 【发布时间】:2019-11-22 04:40:58 【问题描述】:我是SQL Server partitioning
的新手。我已经尝试了一些教程,最后我得到了this 基于它创建了一个分区,但问题是我无法像mysql
查询中那样检索基于分区的数据
SELECT * FROM TABLE_NAME PARTITION(partitionId)
并且还在SQL Server
中尝试过这个查询
SELECT $PARTITION.partition_function (partition_function_id)
编辑:
图为表中的数据,我根据日期创建了分区,我喜欢根据分区名检索数据,如果分区名是20170203,我排除了那个日期的结果。
【问题讨论】:
可以分享表格数据和预期输出吗? 我已经进行了编辑,检查一次@HardikLeuwa 【参考方案1】:select * from TABLE_NAME
where $partition.fpartfunction(date) = 1
这将返回分区 1 中的所有数据。
如果您想从日期开始检索它,您可以执行以下操作,
CREATE PARTITION FUNCTION PF_Date(date) AS RANGE LEFT FOR VALUES('2017-01-01','2018-01-01');
--first partition
SELECT *
FROM schema.table_name
WHERE key_column <= '2017-01-01';
--second partition
SELECT *
FROM schema.table_name
WHERE key_column > '2017-01-01' AND key_column <= '2018-01-01';
--last partition
SELECT *
FROM schema.table_name
WHERE key_column > '2018-01-01';
【讨论】:
只有那个 SQL Server 吗?【参考方案2】:我希望这可以满足您的需要:
CREATE PROCEDURE USP_GetRowsWithinPartition (@InputDate DATE)
AS
BEGIN
DECLARE @TV TABLE
(StartDate DATE,
EndDate DATE
)
INSERT INTO @TV (StartDate, EndDate)
SELECT TOP 1
CAST((CASE
WHEN (DATEPART(MONTH, @InputDate)) = 7 AND (DATEPART(DAY, @InputDate)) > 2
THEN DATEADD(YEAR, -1, CONVERT(DATE, prv.Value, 116))
WHEN (DATEPART(MONTH, @InputDate)) > 7 AND (DATEPART(DAY, @InputDate)) >= 1
THEN DATEADD(YEAR, -1, CONVERT(DATE, prv.Value, 116))
ELSE prv.Value
END) AS DATE) AS StartDate,
CAST((CASE
WHEN (DATEPART(MONTH, @InputDate)) = 7 AND (DATEPART(DAY, @InputDate)) > 2
THEN prv.Value
WHEN (DATEPART(MONTH, @InputDate)) > 7 AND (DATEPART(DAY, @InputDate)) >= 1
THEN prv.Value
ELSE DATEADD(YEAR, 1, CONVERT(DATE, prv.Value, 116))
END ) AS DATE) AS EndDate
FROM sys.partition_functions pf
INNER JOIN sys.partition_schemes AS ps ON ps.function_id = pf.function_id
INNER JOIN sys.destination_data_spaces AS dds ON dds.partition_scheme_id = ps.data_space_id
INNER JOIN sys.dm_db_partition_stats pstats ON pstats.partition_number = dds.destination_id
INNER JOIN sys.partitions p ON p.partition_id = pstats.partition_id
INNER JOIN sys.data_spaces AS ds ON dds.data_space_id = ds.data_space_id
INNER JOIN sys.partition_range_values AS prv ON pf.function_id = prv.function_id
WHERE pstats.object_id = OBJECT_ID('YourTable')
GROUP BY prv.boundary_id, prv.value
ORDER BY ABS(DATEDIFF(DAY, @InputDate, Convert(DATE, value, 116)))
SELECT yt.* FROM YourTable yt
INNER JOIN @TV t ON yt.DateColumn>=t.StartDate AND yt.DateColumn < t.EndDate
END
EXEC USP_GetRowsWithinPartition '2015-08-01'
【讨论】:
嗨@KGRed,如果您不介意,您能尽快详细说明代码吗.. JOIN 中的系统视图用于定位特定表 (YourTable) 上的确切分区。 ------- ORDER BY ABS(DATEDIFF(SECOND, @InputDate, Convert(DATE, value, 116))) 和 TOP 1 :用于从 [sys] 的“值”列中的值获取最近的日期。[分区范围值]。 ------- CASE 语句:用于获取特定分区范围的开始和结束日期,在这种情况下为一年。 7 月 3 日是年中:当输入日期在第二个半年时,前 1 个值将是结束日期,反之亦然。 CASE 语句用于获取开始和结束日期。【参考方案3】:(MySQL)
访问特定的PARTITION
几乎没有用处。您应该让WHERE
子句选择要使用的分区。
此外,分区的用途很少。我建议您在拥有大量经验之前忽略该功能。
任何,回答你的问题......是的,这应该工作:
SELECT * FROM TABLE_NAME PARTITION(partitionId);
但这直到 5.6 才可用。
partitionid 可能需要被引用,特别是如果它是一个数字。如需进一步研究,请提供SHOW CREATE TABLE
。
【讨论】:
以上是关于从 SQL Servertable 中的分区中检索数据的主要内容,如果未能解决你的问题,请参考以下文章