从 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 中的分区中检索数据的主要内容,如果未能解决你的问题,请参考以下文章

重组现有 SQL Server 表中的序列

从 ASP.NET 中的 SQL 数据库中检索 HTML 代码

使用 pyodbc 从 SQL 中检索数据

通过自定义分区器对雪花中的大表进行分区

如何从 SQL Server 中的存储过程中检索参数列表

从sql中的表中检索前n个字母[重复]