我正在通过复制的 SQL Server 数据库访问和创建来自供应商的报告。他们做了一些我一直试图解决的绝对疯狂的事情,但这个问题占据了上风。
他们有一个包含许多标准列的表。但是这个表还有一个叫做“数据”的列。该列是传统的“文本”数据类型,它包含一个巨大的(数百个)键/值对列表。每对由 CRLF 分隔,键和值由等号分隔。例子:
select myTable.[data] from myTable where tblKey = 123
Run Code Online (Sandbox Code Playgroud)
结果:
Key 1=Value 1
Key 2=Value 2
Key 3=Value 3
...
Key 500=Value 500
Run Code Online (Sandbox Code Playgroud)
我正在尝试确定将该列分解为可用数据表的最有效方法。最终目标是能够以将表键以及指定键/值作为列/字段返回的方式查询表:
tblKey | [Key 1] | [Key 3] | [Key 243]
-------|---------|---------|-----------
123 Value 1 Value 3 Value 243
124 Value 1 Value 3 Value 243
125 Value 1 Value 3 Value 243
Run Code Online (Sandbox Code Playgroud)
有没有办法将该列塑造成一个视图?我无法想象一个函数会特别有效,但我确信我可以使用 string_split 或类似的东西来解析事情。有没有人以前遇到过这种暴行并找到了一种将其操纵成可用数据的好方法?
编辑以添加dbfiddle示例数据。
数据是从供应商的来源复制的,因此我无法创建新表。我可以创建视图、过程和函数。这就是我正在寻找一种体面的方式来完成的建议。
不确定这是否或多或少适合提出这个问题,最初是在Stack Overflow 上提出的。
在SQL Server 2008中我有一个观点V在表A和B看起来大致是
create view V as
select * from A
union all
select * from B
Run Code Online (Sandbox Code Playgroud)
读取V导致查询在基表上获取意图共享锁,但也会在视图对象本身上获取意图共享锁。
很明显为什么我们需要表上的 IS 锁,并且我们可以看到视图上的 IS 锁阻止了对视图底层表的并发修改。没关系。
查询计划没有提及视图。它是完全编译出来的,在这种情况下生成的计划是来自两个基表的行的简单串联。实际上,查询计划 XML 中唯一提到的视图是在语句文本中。
如果您U在表上添加第二个视图,则读取V不会导致任何锁定U。这排除了引擎只对A和上的所有视图进行 IS 锁定B。
数据库引擎如何知道锁定视图?
如果是后者,存储引擎知道锁定视图的机制的细节可以被认为是内部的。然而,它这样做的事实是用户可见的,我希望它在某处被记录下来。
我希望提高 SQL Server 2008 中视图的性能。这个视图存在于一个报告数据库中,非技术人员广泛使用该数据库来基本上对一个人的所有这些属性进行非规范化。
这是一个非常复杂的长期运行视图。我们有超过 1900 万人,每一列都有很多逻辑。例如,有一个关于一个人是否已故的指标,它依赖于三个 CTE(公共表表达式)和一个 case 语句。
基本上,这是一场噩梦。
我需要想办法提高性能。无法将其更改为表格 - 数据必须准确无误。将其更改为索引视图是正确的 - 它使用来自多个数据库的数据。我无法真正修改列结构,因为它会破坏许多现有报告。
工具箱中是否有可能有帮助的工具?我想知道存储过程或函数是否有帮助。也许是一个带有计算列的表?我将能够每晚提取此人的识别信息并将其存储到表格中,但绝大多数列依赖于实时数据。
performance sql-server-2008 database-design sql-server view query-performance
MYSQL 视图占用物理空间吗?或者换句话说,MYSQL 数据库是否仅限于一定数量的视图?
我知道视图是使用规则系统实现的,但我不清楚在针对它们运行事务性 DDL 时这是否有任何优点/缺点。发出CREATE OR REPLACE VIEW ...;或DROP VIEW ...; CREATE VIEW...;在事务中是否会针对表取出类似于 DDL的ACCESS EXCLUSIVE锁?所有在 DDL 之前发出的查询都必须在 DDL 执行之前完成吗?查询会在 DDL 阻塞后发出,直到 DDL 完成吗?
我想编写一个 PostgreSQL 函数,它返回一个表和一个附加列。有没有办法在不手动指定的情况下做到这一点RETURNS TABLE (col1 type, col2 type, ...)?
例如,考虑以下函数:
CREATE FUNCTION get_users_with_most_videos_since_time(ts TIMESTAMPTZ)
RETURNS SETOF "user" AS $$
SELECT
u.*,
count(v.id) AS vids_since
FROM "user" AS u
INNER JOIN "video" AS v ON v.creator_id = u.id
WHERE v.created_at > ts
GROUP BY u.id
ORDER BY vids_since DESC;
$$ LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)
这失败并出现错误:
Run Code Online (Sandbox Code Playgroud)ERROR: return type mismatch in function declared to return "user" DETAIL: Final statement returns too many columns.
公平地说,我们包括了该vids_since列,该列不存在于"user"表中。
因此,要解决此问题,我想将其更改为:
CREATE FUNCTION get_users_with_most_videos_since_time(ts …Run Code Online (Sandbox Code Playgroud) 我有一个名为的数据库DDOS_WAF_REPORT,其中包含多个名称格式dbo.DDOS_WAF_ACCOUNT_######(5 位或 6 位 ID 号)的表。
所有表都具有完全相同的结构(列名和类型)。我想UNION ALL一起为他们创建一个视图。此外,还会有相同类型的新表稍后添加到数据库中,因此我需要视图能够“遍历”数据库中的所有现有表并添加它们(添加或创建视图)划痕)。
我已经用硬编码的表名创建了一个简单的视图,但是我很难解决动态创建视图的问题。我正在使用 SQL Server 2012。
添加的表是针对每个帐户的 API 运行的外部脚本的结果,因此我无法避免数据库中有多个表。我假设我可能需要编写一些脚本代码来实际运行并检查新表名,但我想看一些例子来弄清楚如何做到这一点。
执行计划作为查询
SELECT VP.Branch
, VP.ROUTE AS Route
, VP.SAPCustomerID
, S.CustomerID
, S.ProductID
, S.Date
-- Group by Customer
, CustomerQuantity = SUM(S.Quantity) OVER (PARTITION BY VP.Branch, VP.ROUTE, VP.SAPCustomerID, S.ProductID, S.Date)
, CustomerFourWeekSalesAvg = SUM(S.FourWeekSalesAvg) OVER (PARTITION BY VP.Branch, VP.ROUTE, VP.SAPCustomerID, S.ProductID, S.Date)
-- Group by Route
, SUM(S.Quantity) OVER (PARTITION BY VP.Branch, VP.ROUTE, S.ProductID, S.Date) AS RouteQuantity
, RouteFourWeekSalesAvg = SUM(S.FourWeekSalesAvg) OVER (PARTITION BY VP.Branch, VP.ROUTE, S.ProductID, S.Date)
-- Group by Branch
, BranchQuantity = SUM(S.Quantity) OVER (PARTITION BY …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan view sql-server-2016 query-performance
对于表,我可以实现“如果不存在”和“如果存在”如下:
--if table exists - drop
If OBJECT_ID('A','U') is not null
Drop Table [A]
--if table not exists - Create
If OBJECT_ID('A','U') is null
Create Table A([key] varchar(20), [value] varchar(max))
Run Code Online (Sandbox Code Playgroud)
但它在视图和触发器上的作用并不完全相同
我可以:
-- if exists - drop
If OBJECT_ID('VA','V') is not null
Drop view [VA]
Run Code Online (Sandbox Code Playgroud)
但是当我尝试相反的时候:
-- if not exists - create
If OBJECT_ID('VA','V') is null
Create view [VA] as Select * from [A]
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
关键字“view”附近的语法不正确
触发器也是如此。当我做:
-- if not exists - create
If OBJECT_ID('Trigger_A_ins','TR') is null
Create trigger [Trigger_A_ins] …Run Code Online (Sandbox Code Playgroud) 我正在和一位同事讨论解决问题的方法。
我们有一个表来跟踪填充过程,该表在列Lot和上具有唯一的索引列(或至少应该) TestGrade。
最近,我们添加了逻辑,以便当TestGrade创建大于 1 的任何值时,所有较低级别都会被创建。完成了一些逻辑,因此较低级别的行不一定与顶层相同。
例如,我插入一些东西Lot='ABCD',TestGrade=5然后在我的Fills表中我看到
id Lot TestGrade OtherColumns
======================================
10 'ABCD' 1 blah3
9 'ABCD' 2 bar
8 'ABCD' 3 foo
7 'ABCD' 4 blah1
6 'ABCD' 5 blah
Run Code Online (Sandbox Code Playgroud)
现在的问题是在许多情况下,我只想要 Fills 表的顶级记录,因此在示例中,我只想要带有id=6.
关于如何做到这一点,我们有两个想法。我想做一个看起来像
CREATE VIEW [dbo].[vwFills]
AS
SELECT t.* FROM [dbo].[Fills] t
JOIN (SELECT [Lot], MAX(TestGrade) as TestGrade FROM dbo.Fills GROUP BY [Lot]) t2 ON t.[Lot] = t2.[Lot] AND t.[TestGrade] = t2.[TestGrade]
Run Code Online (Sandbox Code Playgroud)
我的同事想做类似的事情,但在一个看起来像这样的函数内
ALTER …Run Code Online (Sandbox Code Playgroud) view ×10
sql-server ×7
functions ×2
locking ×2
performance ×2
postgresql ×2
datatypes ×1
ddl ×1
dynamic-sql ×1
join ×1
mysql ×1
storage ×1
trigger ×1