【问题标题】:Create a pseudo column to display Yes/No if one column value is present in another for a particular id创建一个伪列以显示是/否,如果一个列值存在于另一个特定 id
【发布时间】:2022-11-19 13:35:44
【问题描述】:

我有一个具有以下结构的表:

create table test_18Nov ( account_id nvarchar(12)
                        , account_name nvarchar(25)
                        , zip_legacy_file nvarchar(5)
                        , Region_legacy_file nvarchar(30)
                        , zip_new_source nvarchar(5)
                        , Region_new_source nvarchar(30)
                        )

INSERT INTO test_18Nov VALUES ('S1018', 'John Smith',       '32221', 'R087-Jacksonville',   '33803', 'R026-Lakeland')
INSERT INTO test_18Nov VALUES ('S1018', 'John Smith',       '33606', 'R011-Tampa',          '32220', 'R087-Jacksonville')
INSERT INTO test_18Nov VALUES ('S1018', 'John Smith',       '33803', 'R026-Lakeland',       '33606', 'R011-Tampa')
INSERT INTO test_18Nov VALUES ('AC054', 'David Thompson',   '33606', 'R011-Tampa',          '32205', 'R087-Jacksonville')
INSERT INTO test_18Nov VALUES ('AC054', 'David Thompson',   '33870', 'R058-Sebring',        '33606', 'R011-Tampa')
INSERT INTO test_18Nov VALUES ('AC054', 'David Thompson',   '33610', 'R011-Tampa',          '33870', 'R058-Sebring')
INSERT INTO test_18Nov VALUES ('AC077', 'Stacey Leigh',     '34950', 'R043-Fort Pierce',    '34982', 'R043-Fort Pierce')
INSERT INTO test_18Nov VALUES ('AC077', 'Stacey Leigh',     '33610', 'R011-Tampa',          '34950', 'R043-Fort Pierce')

我必须为所有带有“是”或“否”的行生成一个伪列。 对于帐户 ID,如果旧区域(或区域)存在于新源区域(或区域)中,则伪列将显示“否”。如果帐户的新源区域(或区域)不存在于遗留区域(或区域)中,则该帐户将被视为移动,伪列将显示“是”。在上面的数据集中,AC054 是唯一一个应该将伪列值设置为“是”的帐户 ID,因为 R087-Jacksonville(一个新的源区域)不在旧区域列表中。

预期的输出应该是:

account_id  | account_name      |  Region_legacy_file   | Region_new_source     | Will the account move?    |
-------------------------------------------------------------------------------------------------------------
S1018       | John Smith        | R087-Jacksonville     | R026-Lakeland         |       No                  |
-------------------------------------------------------------------------------------------------------------
S1018       | John Smith        | R011-Tampa            | R087-Jacksonville     |       No                  |
-------------------------------------------------------------------------------------------------------------
S1018       | John Smith        | R026-Lakeland         | R011-Tampa            |       No                  |
-------------------------------------------------------------------------------------------------------------
AC054       | David Thompson    | R011-Tampa            | R087-Jacksonville     |       Yes                 |
-------------------------------------------------------------------------------------------------------------
AC054       | David Thompson    | R058-Sebring          | R011-Tampa            |       Yes                 |
-------------------------------------------------------------------------------------------------------------
AC054       | David Thompson    | R011-Tampa            | R058-Sebring          |       Yes                 |
-------------------------------------------------------------------------------------------------------------
AC077       | Stacey Leigh      | R043-Fort Pierce      | R043-Fort Pierce      |       No                  |
-------------------------------------------------------------------------------------------------------------
AC077       | Stacey Leigh      | R011-Tampa            | R043-Fort Pierce      |       No                  |
-------------------------------------------------------------------------------------------------------------

我考虑过使用 NOT EXISTS 子句,但它只会返回在帐户 ID 的遗留区域列表中未找到新源区域的行 - 在这种情况下这对我没有任何帮助。我能想到的唯一方法是使用 CASE WHEN EXISTS 但无法让它工作。如果有任何其他方式,请分享。

编辑 : 为什么 AC054 的伪列为“是”? - 帐户 ID AC054 有 3 个新的源区域,它们是 R087、R011 和 R058。在这 3 个区域中,有 2 个区域位于帐户 ID AC054 的遗留区域中,它们是 R011 和 R058。因此 R087 不是帐户 ID AC054 的遗留区域列表的一部分,因此伪列具有“是”。对于其他 2 个帐户 ID,情况并非如此,因为所有新的源区域都在遗留区域列表中找到。

【问题讨论】:

  • 老实说,我仍然无法理解你判断真假的标准
  • 如果您让它为一行而不是整个帐户工作,请使用窗口函数来传播剩余行的结果。 MAX(your_expression) OVER (PARTITION BY account_id) AS move_yes_no
  • @nbk - 如果您查看帐户 ID AC054 的数据,您会注意到两个旧区域都存在于新的源区域中。但是来自新源区域的 R087 不存在于遗留区域中。这还不清楚吗?
  • @Arty155 不,我真的不明白 sevrina 和 tampa 是如何相互关联的,所以我根本不明白为什么应该移动它们,必须有一个基础表格来解释为什么哪个组合适合而另一个不适合
  • @nbk - 没有其他表,也没有地理联系。我刚刚举了一个例子。这些值也可能是区域 1-ABC、区域 2-TGV、区域 3 或您能想到的任何字符组合。逻辑是针对特定帐户 ID,新源区域不应出现在遗留区域中。我在我的开篇文章中编辑了预期的输出。希望更少的列可以帮助可视化数据。

标签: sql sql-server sql-server-2014


【解决方案1】:

您可以使用 SQL 子查询,这意味着您对每一行都执行另一个查询来查找结果,例如:

SELECT name, id, location, (SELECT TOP 1 'exists' FROM location l WHERE l.location = c.location) 
FROM customer c

【讨论】:

  • 客户 c 和位置 l 是 2 个不同的表。我只有一张桌子。自我加入也是基于帐户 ID,但比较两种区域 - 旧源和新源。
【解决方案2】:

我正在检查您的信息,我做了一个示例,子查询 CheckLegacy 将返回应该移动的帐户,遵循示例:

WITH test_18Nov  AS (
    SELECT * FROM (
    VALUES
        ('S1018', 'John Smith',       '32221', 'R087-Jacksonville',   '33803', 'R026-Lakeland'), 
        ('S1018', 'John Smith',       '33606', 'R011-Tampa',          '32220', 'R087-Jacksonville'), 
        ('S1018', 'John Smith',       '33803', 'R026-Lakeland',       '33606', 'R011-Tampa'), 
        ('AC054', 'David Thompson',   '33606', 'R011-Tampa',          '32205', 'R087-Jacksonville'), 
        ('AC054', 'David Thompson',   '33870', 'R058-Sebring',        '33606', 'R011-Tampa'),
        ('AC054', 'David Thompson',   '33610', 'R011-Tampa',          '33870', 'R058-Sebring'),
        ('AC077', 'Stacey Leigh',     '34950', 'R043-Fort Pierce',    '34982', 'R043-Fort Pierce'),
        ('AC077', 'Stacey Leigh',     '33610', 'R011-Tampa',          '34950', 'R043-Fort Pierce')
    ) AS _ (account_id,account_name, zip_legacy_file,Region_legacy_file,zip_new_source,Region_new_source)
),
--formatting the query for the field I need
IdAndNewLegacy as (
    SELECT account_id, Region_new_source FROM test_18Nov
),
--check if some new legacy region is not in Region_legacy_file
CheckLegacy as (
    SELECT I.account_id, T.account_id as id FROM IdAndNewLegacy as I
    LEFT JOIN test_18Nov as T ON I.account_id = T.account_id and I.Region_new_source = T.Region_legacy_file
    WHERE T.account_id is null
    GROUP BY I.account_id, T.account_id
)
--Query to present the data
SELECT 
    t.*,
    CASE WHEN c.account_id is not null then 'Yes' ELSE 'No' END as [Will the account move?]
FROM 
    test_18Nov  as t
    LEFT JOIN CheckLegacy as c ON T.account_id = C.account_id 

结果:

此致

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2021-09-06
    相关资源
    最近更新 更多