- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力将来自第 3 方系统的一些数据集成到我的一个应用程序中(基于 ASP Classic 的传统 Web 应用程序/SQL 2000) - 他们在方法方面做出了一些糟糕的决定(恕我直言)和数据结构,尽管也许我们可能有机会在某个时候进行重构……但在那之前,我必须处理眼前的事情。
主表保存检查数据,其中一个字段用于记录是否观察到某些特征。这些特征存储在名为 Categories
的表中,但不幸的是,主检查表 (Test
) 通过连接相关的 CategoryID
链接到类别到单个字段(SelectedCategories
)。因此,例如,如果观察到特征 01 和 02,则 Test
中该行的 SelectedCategories
列的值为“01C02C”。
修剪后的 DDL:
CREATE TABLE [dbo].[Test](
[ItemID] [varchar](255) NOT NULL,
[Result] [varchar](255) NULL,
[Comments] [varchar](255) NULL,
[ResultReason] [varchar](255) NULL,
[ImageLocation] [varchar](255) NULL,
[TestDateTime] [smalldatetime] NOT NULL,
[SelectedCategories] [varchar](255) NULL)
问题是,在这种情况下,我如何才能最好地从 Test
中提取数据并分割观察到的特征?
我想要的客户端输出是一个包含以下列的表:Test.PK、Test.Field2...Test.Fieldn、类别.ID1、类别.ID2、类别.IDn
这可能还不够清楚 - 第一个字段是 Test
中的常见字段,后面是 中每个类别的勾号或叉号(或其他一些视觉指示符)类别
。
显然,如果可以在一次查询中实现这一点,那么在效率和性能方面就更好了。但是,我不确定如何实现这一点 - 如何通过 SelectedCategories
加入 Categories
表?
我显然可以简单地报告SelectedCategories
值并让应用程序解析该值。这可能是硬编码的,或者更有可能我们会为测试中的每一行重新查询类别 - 尽管这会对性能产生影响。说实话,在这种情况下,性能可能不是问题,但仅仅因为你可以侥幸逃脱某些事情,并不意味着你应该养成它的习惯。
同样,如果我有机会重构第 3 方应用程序,我是否会删除 SelectedCategories
列并添加 TestCategories
表?或者我会将每个类别硬编码为一系列位列。在系统的整个生命周期中,类别
很可能不会发生变化,但如果发生变化,则意味着数据库和应用程序都会发生变化(尽管非常微小)。
我希望我已经解释得足够清楚了。本质上,我是说如果我坚持使用当前系统,最好的方法是什么?如果我要重构,我可以采取什么不同的方法?
进度更新:
非常感谢 Lieven,到目前为止我已经得到了:
DML:
SELECT c.ID, c.Category, t.FilterID, t.OperatorResult, t.SelectedCategories
FROM dbo.Categories c
inner JOIN dbo.Test t ON CHARINDEX(Cast(c.ID as varchar), t.SelectedCategories, 1) <> 0
order by FilterID, ID
输出:
ID Category FilterID OperatorResult SelectedCategories
4 Cracked Ceramic 137667 FAILED 04C
4 Cracked Ceramic 284821 FAILED 04C
4 Cracked Ceramic 287617 FAILED 04C05C
5 Damaged Case 287617 FAILED 04C05C
4 Cracked Ceramic 310112 FAILED 04C05C
5 Damaged Case 310112 FAILED 04C05C
这就足够了,除了为了达到我想要的屏幕输出......
Filter ID Operator Result Cat Matl Crack Damage High Soot
137667 FAILED X X
178643 FAILED
284821 FAILED X
287617 FAILED X X
310112 FAILED X X
...我要么需要对 SQL 进行进一步的工作(以便我可以在一个查询中实现所需的输出),要么需要在应用程序本身中做一些额外的工作。
结论:
如果我们看一下 Lieven 的最新示例(如下),我们可以看到该问题可以在 TSQL 中解决,但类别是硬编码的。
另一种选择是坚持原始数据并让 IIS/ASP 做更多工作。它肯定会使源代码变得复杂,但如果添加或删除类别,则会消除更新 TSQL 的潜在开销。我当然可以忍受这种偶尔需要更新 TSQL 的情况,但我正在提前考虑不同的问题,其中类别表将定期主动更改。
最佳答案
通过SelectedCategories
加入Categories
表可以像这样工作
一些值得思考的事情
请告诉我们它是否适合您。
BEGIN TRAN
CREATE TABLE [dbo].[Categories](
[CategorieID] INTEGER NOT NULL)
CREATE TABLE [dbo].[Test](
[ItemID] [varchar](255) NOT NULL,
[Result] [varchar](255) NULL,
[Comments] [varchar](255) NULL,
[ResultReason] [varchar](255) NULL,
[ImageLocation] [varchar](255) NULL,
[TestDateTime] [smalldatetime] NOT NULL,
[SelectedCategories] [varchar](255) NULL)
INSERT INTO dbo.Categories VALUES (4)
INSERT INTO dbo.Categories VALUES (5)
INSERT INTO dbo.Test VALUES (137667, 'FAILED', NULL, 'Cracked Ceramic', NULL, GetDate(), '04C')
INSERT INTO dbo.Test VALUES (284821, 'FAILED', NULL, 'Cracked Ceramic', NULL, GetDate(), '04C')
INSERT INTO dbo.Test VALUES (287617, 'FAILED', NULL, 'Cracked Ceramic', NULL, GetDate(), '04C05C')
INSERT INTO dbo.Test VALUES (287617, 'FAILED', NULL, 'Damaged Case' , NULL, GetDate(), '04C05C')
INSERT INTO dbo.Test VALUES (310112, 'FAILED', NULL, 'Cracked Ceramic', NULL, GetDate(), '04C05C')
INSERT INTO dbo.Test VALUES (310112, 'FAILED', NULL, 'Damaged Case' , NULL, GetDate(), '04C05C')
SELECT [Filter ID] = t.ItemID
, [Operator Result] = t.Result
, [Reason] = t.ResultReason
INTO #Output
FROM dbo.Categories c
LEFT OUTER JOIN dbo.Test t ON
/* Search for "C<{00}CategorieID>C" */
CHARINDEX('C' -- Prefix CategorieID & SelectedCategories with 'C'
+ REPLICATE('0', 2 - LEN(CAST(CategorieID AS VARCHAR))) -- Left Pad CategorieID with '0'
+ CAST(CategorieID AS VARCHAR) -- Add CategorieID itself
+ 'C' -- Suffix search string with 'C'.
, 'C' + t.SelectedCategories -- Prefix CategorieID & SelectedCategories with 'C'
, 1) <> 0
SELECT [Filter ID]
, [Operator Result]
, [Cat Matl] = CASE WHEN [Cat Matl] = 1 THEN 'X' ELSE '' END
, [Crack] = CASE WHEN [Crack] = 1 THEN 'X' ELSE '' END
, [Damage] = CASE WHEN [Damage] = 1 THEN 'X' ELSE '' END
, [High Soot] = CASE WHEN [High Soot] = 1 THEN 'X' ELSE '' END
FROM (
SELECT [Filter ID]
, [Operator Result]
, [Cat Matl] = MAX(CASE WHEN Reason = 'Cat Matl' THEN 1 ELSE 0 END)
, [Crack] = MAX(CASE WHEN Reason = 'Cracked Ceramic' THEN 1 ELSE 0 END)
, [Damage] = MAX(CASE WHEN Reason = 'Damaged Case' THEN 1 ELSE 0 END)
, [High Soot] = MAX(CASE WHEN Reason = 'High Soot' THEN 1 ELSE 0 END)
FROM #Output
GROUP BY [Filter ID]
, [Operator Result]
) o
DROP TABLE #Output
ROLLBACK TRAN
关于sql-server - 在设计不良的模式中进行复杂查询的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2244303/
我有三张 table 。表 A 有选项名称(即颜色、尺寸)。表 B 有选项值名称(即蓝色、红色、黑色等)。表C通过将选项名称id和选项名称值id放在一起来建立关系。 我的查询需要显示值和选项的名称,而
在mysql中,如何计算一行中的非空单元格?我只想计算某些列之间的单元格,比如第 3-10 列之间的单元格。不是所有的列...同样,仅在该行中。 最佳答案 如果你想这样做,只能在 sql 中使用名称而
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
我正在为版本7.6进行Elasticsearch查询 我的查询是这样的: { "query": { "bool": { "should": [ {
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 7 年前。 Improve this ques
是否可以编写一个查询来检查任一子查询(而不是一个子查询)是否正确? SELECT * FROM employees e WHERE NOT EXISTS (
我找到了很多关于我的问题的答案,但问题没有解决 我有表格,有数据,例如: Data 1 Data 2 Data 3
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
以下查询返回错误: 查询: SELECT Id, FirstName, LastName, OwnerId, PersonEmail FROM Account WHERE lower(PersonEm
我从 EditText 中获取了 String 值。以及提交查询的按钮。 String sql=editQuery.getText().toString();// SELECT * FROM empl
我有一个或多或少有效的查询(关于结果),但处理大约需要 45 秒。这对于在 GUI 中呈现数据来说肯定太长了。 所以我的需求是找到一个更快/更高效的查询(几毫秒左右会很好)我的数据表大约有 3000
这是我第一次使用 Stack Overflow,所以我希望我以正确的方式提出这个问题。 我有 2 个 SQL 查询,我正在尝试比较和识别缺失值,尽管我无法将 NULL 字段添加到第二个查询中以识别缺失
什么是动态 SQL 查询?何时需要使用动态 SQL 查询?我使用的是 SQL Server 2005。 最佳答案 这里有几篇文章: Introduction to Dynamic SQL Dynami
include "mysql.php"; $query= "SELECT ID,name,displayname,established,summary,searchlink,im
我有一个查询要“转换”为 mysql。这是查询: select top 5 * from (select id, firstName, lastName, sum(fileSize) as To
通过我的研究,我发现至少从 EF 4.1 开始,EF 查询上的 .ToString() 方法将返回要运行的 SQL。事实上,这对我来说非常有用,使用 Entity Framework 5 和 6。 但
我在构造查询来执行以下操作时遇到问题: 按activity_type_id过滤联系人,仅显示最近事件具有所需activity_type_id或为NULL(无事件)的联系人 表格结构如下: 一个联系人可
如何让我输入数据库的信息在输入数据 5 分钟后自行更新? 假设我有一张 table : +--+--+-----+ |id|ip|count| +--+--+-----+ |
我正在尝试搜索正好是 4 位数字的 ID,我知道我需要使用 LENGTH() 字符串函数,但找不到如何使用它的示例。我正在尝试以下(和其他变体)但它们不起作用。 SELECT max(car_id)
我有一个在 mysql 上运行良好的 sql 查询(查询 + 连接): select sum(pa.price) from user u , purchase pu , pack pa where (
我是一名优秀的程序员,十分优秀!