提问人:Juan Daniel 提问时间:11/14/2023 更新时间:11/14/2023 访问量:54
如果表中存在某些值,如何将值设置为“1”,否则将值设置为“0”?
How can I set a value to '1' if certain values exist in a table and set a value to '0' otherwise?
问:
我有一个名为 Books 的数据库,该数据库有一个名为 PrimaryBooks 的表,其中包含以下数据:
Title Pages DateOfRelease
Sapiens 572 1987-01-20
Black Swan 852 2004-07-14
1984 429 1949-12-03
Influence 1582 2017-06-17
Freakonomics 826 2014-11-26
The Alchemist 371 2001-02-07
Quiet 639 2016-08-29
Blink 198 2022-04-11
The Art of War 2485 1772-09-10
该数据库还有另一个名为 SECONDARYBOOKS 的表,其中包含以下数据(它们相似。但是,此表还有两列,分别称为 COLOR 和 PRICE。其他列的名称与第一个表中的名称相同,但采用 Caps 形式,虽然列中的许多数据与其他表相同,但某些值略有不同):
COLOR PRICE TITLE PAGES DATEOFRELEASE
Green 17 Sapiens 834 1987-01-20
Black 25 Black Swan 852 2004-07-14
Gray 28 1984 429 1949-12-03
Orange 12 Influence 1582 2018-05-16
Red 31 Freakonomics 826 2014-11-26
White 37 The Alchemist 371 2001-02-07
Cyan 10 Meditations 1004 2016-08-29
Blue 18 Deep Work 624 2023-01-12
Yellow 29 The Art of War 2485 1672-09-10
我想做的是在表 SECONDARYBOOKS(必须称为 status)中添加一个新列,它将显示 0 或 1。如果行中的数据与第一个表中的数据完全相同,则显示 1(COLOR 和 PRICE 除外,因为第一个表没有该数据),如果不是,则显示 0。这意味着该表最终必须如下所示:
COLOR PRICE TITLE PAGES DATEOFRELEASE STATUS
Green 17 Sapiens 834 1987-01-20 0
Black 25 Black Swan 852 2004-07-14 1
Gray 28 1984 429 1949-12-03 1
Orange 12 Influence 1582 2018-05-16 0
Red 31 Freakonomics 826 2014-11-26 1
White 37 The Alchemist 371 2001-02-07 1
Cyan 10 Meditations 1004 2016-08-29 0
Blue 18 Deep Work 624 2023-01-12 0
Yellow 29 The Art of War 2485 1672-09-10 0
我想知道我怎样才能做到这一点。
我尝试编写以下查询:
SELECT CASE WHEN PB1.Title = SB.TITLE THEN
CASE WHEN PB2.Pages = SB.PAGES THEN
CASE WHEN SUBSTRING(CONVERT(varchar(15), PB3.DateOfRelease, 112), 1, 8) = SUBSTRING(CONVERT(varchar(15), SB.DATEOFRELEASE, 112), 1, 8) THEN
'1'
ELSE
'0'
END
ELSE
0'
END
ELSE
'0'
END
AS STATUS
FROM SECONDARYBOOKS SB
LEFT JOIN PrimaryBooks PB1 ON PB1.Title = SB.TITLE
LEFT JOIN PrimaryBooks PB2 ON PB2.Pages = SB.PAGES
LEFT JOIN PrimaryBooks PB3 ON PB3.DateOfRelease = SB.DATEOFRELEASE
GROUP BY SB.COLOR, SB.PRICE, SB.TITLE, SB.PAGES, SB.DATEOFRELEASE, PB1.Title, PB2.Pages, PB3.DateOfRelease
但是,当我执行此查询时,它永远不会停止尝试执行。它被卡住了。
答:
请尝试以下解决方案。
SQL算法
-- DDL and sample data population, start
DECLARE @tbl_books TABLE (Title VARCHAR(50), Pages INT, DateOfRelease DATE);
INSERT @tbl_books (Title, Pages, DateOfRelease) VALUES
('Sapiens', 572 , '1987-01-20'),
('Black Swan', 852 , '2004-07-14'),
('1984', 429 , '1949-12-03'),
('Influence', 1582, '2017-06-17'),
('Freakonomics', 826 , '2014-11-26'),
('The Alchemist ', 371 , '2001-02-07'),
('Quiet', 639 , '2016-08-29'),
('Blink', 198 , '2022-04-11'),
('The Art of War', 2485, '1772-09-10');
DECLARE @tbl_secondarybooks TABLE (COLOR VARCHAR(20), PRICE INT, Title VARCHAR(50), Pages INT, DateOfRelease DATE);
INSERT @tbl_secondarybooks (COLOR, PRICE, Title, Pages, DateOfRelease) VALUES
('Green', 17, 'Sapiens', 834 , '1987-01-20'),
('Black', 25, 'Black Swan', 852 , '2004-07-14'),
('Gray', 28, '1984', 429 , '1949-12-03'),
('Orange', 12, 'Influence', 1582, '2018-05-16'),
('Red', 31, 'Freakonomics', 826 , '2014-11-26'),
('White', 37, 'The Alchemist', 371 , '2001-02-07'),
('Cyan', 10, 'Meditations', 1004, '2016-08-29'),
('Blue', 18, 'Deep Work', 624 , '2023-01-12'),
('Yellow', 29, 'The Art of War', 2485, '1672-09-10');
-- DDL and sample data population, end
SELECT sb.*, status = 1
FROM @tbl_secondarybooks AS sb
INNER JOIN @tbl_books AS b ON (sb.Title = b.Title AND sb.Pages = b.Pages AND sb.DateOfRelease = b.DateOfRelease)
UNION ALL
SELECT sb.*, status = 0
FROM @tbl_secondarybooks AS sb
LEFT OUTER JOIN @tbl_books AS b ON (sb.Title = b.Title AND sb.Pages = b.Pages AND sb.DateOfRelease = b.DateOfRelease)
WHERE b.Title IS NULL;
输出
颜色 | 价格 | 标题 | 页面 | DateOfRelease | 地位 |
---|---|---|---|---|---|
黑 | 25 | 黑天鹅 | 852 | 2004-07-14 | 1 |
灰色 | 28 | 1984 | 429 | 1949-12-03 | 1 |
红 | 31 | 怪胎经济学 | 826 | 2014-11-26 | 1 |
白 | 37 | 炼金术士 | 371 | 2001-02-07 | 1 |
绿 | 17 | 智人 | 834 | 1987-01-20 | 0 |
橙 | 12 | 影响 | 1582 | 2018-05-16 | 0 |
青色 | 10 | 冥想 | 1004 | 2016-08-29 | 0 |
蓝 | 18 | 深度工作 | 624 | 2023-01-12 | 0 |
黄色 | 29 | 孙子兵法 | 2485 | 1672-09-10 | 0 |
我不确定你为什么要尝试做三个单独的连接。如果执行了,它将有效地计算出“一些主要书籍具有匹配的标题,一些主要书籍具有匹配的页数,并且某些主要书籍具有匹配的发布日期 - 不一定是同一本书”。我猜你希望所有的东西都与一本主要书籍相匹配。
我希望您想要的是一个测试,它是将状态标志设置为 1 或 0 的表达式的一部分。EXISTS()
CASE
我也不确定为什么在比较似乎已经是日期值的内容之前要进行日期到字符串的转换。如果发布日期列已是 DATE 类型(或具有 00:00:00 时间成分的 DATETIME 类型),则无需进行该转换。
假设您已将该列添加到表中,则可以使用以下更新。status
SECONDARYBOOKS
UPDATE SB
SET status = CASE WHEN EXISTS(
SELECT *
FROM PrimaryBooks PB
WHERE PB.Title = SB.TITLE
AND PB.Pages = SB.PAGES
AND PB.DateOfRelease = SB.DATEOFRELEASE
) THEN 1 ELSE 0 END
FROM SECONDARYBOOKS SB
结果:
颜色 | 价格 | 标题 | 页面 | 发布日期 | 地位 |
---|---|---|---|---|---|
绿 | 17 | 智人 | 834 | 1987-01-20 | 0 |
黑 | 25 | 黑天鹅 | 852 | 2004-07-14 | 1 |
灰色 | 28 | 1984 | 429 | 1949-12-03 | 1 |
橙 | 12 | 影响 | 1582 | 2018-05-16 | 0 |
红 | 31 | 怪胎经济学 | 826 | 2014-11-26 | 1 |
白 | 37 | 炼金术士 | 371 | 2001-02-07 | 1 |
青色 | 10 | 冥想 | 1004 | 2016-08-29 | 0 |
蓝 | 18 | 深度工作 | 624 | 2023-01-12 | 0 |
黄色 | 29 | 孙子兵法 | 2485 | 1672-09-10 | 0 |
有关演示,请参阅此 db<>fiddle。
评论