Sql 选择语句的大小写

Sql 选择语句的大小写,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,请不要贬低这一点,因为我解释起来有点复杂。我正在进行数据迁移,所以有些结构看起来很奇怪,因为它是由这样的人设计的 例如,我有一个PersonID和PersonName作为列的表Person。我桌上有两份 我有一个详细信息表,其中PersonName存储在一列中。Person表中可能存在也可能不存在此PersonName。我需要从匹配的记录中检索PersonID,否则在PersonID中放入一些硬代码值 我不能写下面的查询,因为Person表中的PersonName是重复的,如果由于join而存在

请不要贬低这一点,因为我解释起来有点复杂。我正在进行数据迁移,所以有些结构看起来很奇怪,因为它是由这样的人设计的

例如,我有一个PersonID和PersonName作为列的表Person。我桌上有两份

我有一个详细信息表,其中PersonName存储在一列中。Person表中可能存在也可能不存在此PersonName。我需要从匹配的记录中检索PersonID,否则在PersonID中放入一些硬代码值

我不能写下面的查询,因为Person表中的PersonName是重复的,如果由于join而存在匹配的记录,则此join会使行加倍

SELECT d.Fields, PersonID
FROM Details d
JOIN Person p ON d.PersonName = p.PersonName
下面的查询可以工作,但我不知道如何用我想要的值替换“NULL”

SELECT d.Fields, (SELECT TOP 1 PersonID FROM Person where PersonName = d.PersonName )
FROM Details d
因此,在明细表中有一些人名在Person表中不存在。在这种情况下,如何编写CASE

我在下面试过了,但没用

 SELECT d.Fields, 
       CASE WHEN (SELECT TOP 1 PersonID 
                 FROM Person 
                 WHERE PersonName = d.PersonName) = null 
       THEN 123 
       ELSE (SELECT TOP 1 PersonID 
              FROM Person 
              WHERE PersonName = d.PersonName) END Name
    FROM Details d

此查询仍显示与第二个查询相同的输出。请给我一些建议。如果我不清楚任何地方,请告诉我。很好,谢谢你。。我想我可以把ISNULL放在SELECT上面,让它工作

SELECT d.Fields, 
    ISNULL(SELECT TOP 1 p.PersonID 
           FROM Person p where p.PersonName = d.PersonName, 124) id
    FROM Details d

嗯。。我想我可以把ISNULL放在SELECT上面,让它工作

SELECT d.Fields, 
    ISNULL(SELECT TOP 1 p.PersonID 
           FROM Person p where p.PersonName = d.PersonName, 124) id
    FROM Details d

嗯。。我想我可以把ISNULL放在SELECT上面,让它工作

SELECT d.Fields, 
    ISNULL(SELECT TOP 1 p.PersonID 
           FROM Person p where p.PersonName = d.PersonName, 124) id
    FROM Details d

嗯。。我想我可以把ISNULL放在SELECT上面,让它工作

SELECT d.Fields, 
    ISNULL(SELECT TOP 1 p.PersonID 
           FROM Person p where p.PersonName = d.PersonName, 124) id
    FROM Details d

一个简单的左-外连接可以拉回所有在details表上具有可选匹配项的人员,它应该与case语句一起工作,以获得您想要的结果

SELECT
   *
FROM
(
    SELECT
        Instance=ROW_NUMBER() OVER (PARTITION BY PersonName),
        PersonID=CASE WHEN d.PersonName IS NULL THEN 'XXXX' ELSE p.PersonID END,
        d.Fields
    FROM
        Person p
        LEFT OUTER JOIN Details d on d.PersonName=p.PersonName
)AS X
WHERE
   Instance=1

一个简单的左-外连接可以拉回所有在details表上具有可选匹配项的人员,它应该与case语句一起工作,以获得您想要的结果

SELECT
   *
FROM
(
    SELECT
        Instance=ROW_NUMBER() OVER (PARTITION BY PersonName),
        PersonID=CASE WHEN d.PersonName IS NULL THEN 'XXXX' ELSE p.PersonID END,
        d.Fields
    FROM
        Person p
        LEFT OUTER JOIN Details d on d.PersonName=p.PersonName
)AS X
WHERE
   Instance=1

一个简单的左-外连接可以拉回所有在details表上具有可选匹配项的人员,它应该与case语句一起工作,以获得您想要的结果

SELECT
   *
FROM
(
    SELECT
        Instance=ROW_NUMBER() OVER (PARTITION BY PersonName),
        PersonID=CASE WHEN d.PersonName IS NULL THEN 'XXXX' ELSE p.PersonID END,
        d.Fields
    FROM
        Person p
        LEFT OUTER JOIN Details d on d.PersonName=p.PersonName
)AS X
WHERE
   Instance=1

一个简单的左-外连接可以拉回所有在details表上具有可选匹配项的人员,它应该与case语句一起工作,以获得您想要的结果

SELECT
   *
FROM
(
    SELECT
        Instance=ROW_NUMBER() OVER (PARTITION BY PersonName),
        PersonID=CASE WHEN d.PersonName IS NULL THEN 'XXXX' ELSE p.PersonID END,
        d.Fields
    FROM
        Person p
        LEFT OUTER JOIN Details d on d.PersonName=p.PersonName
)AS X
WHERE
   Instance=1

哦,好极了,有机会使用两个
左连接。第一个将列出存在的ID,否则将插入默认ID;第二种方法将消除重复项

   SELECT d.Fields, ISNULL(p1.PersonID, 123)
     FROM Details d
LEFT JOIN Person p1 ON d.PersonName = p1.PersonName
LEFT JOIN Person p2 ON p2.PersonName = p1.PersonName
                   AND p2.PersonID < p1.PersonID
    WHERE p2.PersonID IS NULL
选择d.字段,为空(p1.PersonID,123)
从细节d
d.PersonName=p1.PersonName上的左连接人p1
在p2.PersonName=p1.PersonName上左键连接人p2
p2.PersonID
Ooh goody,一个使用两个
左连接的机会。第一个将列出存在的ID,否则将插入默认ID;第二种方法将消除重复项

   SELECT d.Fields, ISNULL(p1.PersonID, 123)
     FROM Details d
LEFT JOIN Person p1 ON d.PersonName = p1.PersonName
LEFT JOIN Person p2 ON p2.PersonName = p1.PersonName
                   AND p2.PersonID < p1.PersonID
    WHERE p2.PersonID IS NULL
选择d.字段,为空(p1.PersonID,123)
从细节d
d.PersonName=p1.PersonName上的左连接人p1
在p2.PersonName=p1.PersonName上左键连接人p2
p2.PersonID
Ooh goody,一个使用两个
左连接的机会。第一个将列出存在的ID,否则将插入默认ID;第二种方法将消除重复项

   SELECT d.Fields, ISNULL(p1.PersonID, 123)
     FROM Details d
LEFT JOIN Person p1 ON d.PersonName = p1.PersonName
LEFT JOIN Person p2 ON p2.PersonName = p1.PersonName
                   AND p2.PersonID < p1.PersonID
    WHERE p2.PersonID IS NULL
选择d.字段,为空(p1.PersonID,123)
从细节d
d.PersonName=p1.PersonName上的左连接人p1
在p2.PersonName=p1.PersonName上左键连接人p2
p2.PersonID
Ooh goody,一个使用两个
左连接的机会。第一个将列出存在的ID,否则将插入默认ID;第二种方法将消除重复项

   SELECT d.Fields, ISNULL(p1.PersonID, 123)
     FROM Details d
LEFT JOIN Person p1 ON d.PersonName = p1.PersonName
LEFT JOIN Person p2 ON p2.PersonName = p1.PersonName
                   AND p2.PersonID < p1.PersonID
    WHERE p2.PersonID IS NULL
选择d.字段,为空(p1.PersonID,123)
从细节d
d.PersonName=p1.PersonName上的左连接人p1
在p2.PersonName=p1.PersonName上左键连接人p2
p2.PersonID
您可以使用通用表表达式来构建缺失的数据集,即完整的Person表,然后将其连接到详细信息表,如下所示:

declare @n int;
-- set your default PersonID here;
set @n = 123;

-- Make sure previous SQL statement is terminated with semilcolon for with clause to parse successfully.

-- First build our unique list of names from table Detail.
with cteUniqueDetailPerson
(
    [PersonName]
)
as
(
    select distinct [PersonName]
    from [Details]
)

-- Second get unique Person entries and record the most recent PersonID value as the active Person.
, cteUniquePersonPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
          max([PersonID]) -- if you wanted the original Person record instead of the last, change this to min.
        , [PersonName]
    from [Person]
    group by [PersonName]
)

-- Third join unique datasets to get the PersonID when there is a match, otherwise use our default id @n.
-- NB, this would also include records when a Person exists with no Detail rows (they are filtered out with the final inner join)
, cteSudoPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
        coalesce(upp.[PersonID],@n) as [PersonID]
        coalesce(upp.[PersonName],udp.[PersonName]) as [PersonName]
    from cteUniquePersonPerson upp
    full outer join cteUniqueDetailPerson udp
        on udp.[PersonName] = p.[PersonName]
)

-- Fourth, join detail to the sudo person table that includes either the original ID or our default ID.
select
      d.[Fields]
    , sp.[PersonID]
from [Details] d
inner join cteSudoPerson sp
    on sp.[PersonName] = d.[PersonName];

您可以使用公共表表达式来构建缺少的数据集,即完整的Person表,然后将其连接到Detail表,如下所示:

declare @n int;
-- set your default PersonID here;
set @n = 123;

-- Make sure previous SQL statement is terminated with semilcolon for with clause to parse successfully.

-- First build our unique list of names from table Detail.
with cteUniqueDetailPerson
(
    [PersonName]
)
as
(
    select distinct [PersonName]
    from [Details]
)

-- Second get unique Person entries and record the most recent PersonID value as the active Person.
, cteUniquePersonPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
          max([PersonID]) -- if you wanted the original Person record instead of the last, change this to min.
        , [PersonName]
    from [Person]
    group by [PersonName]
)

-- Third join unique datasets to get the PersonID when there is a match, otherwise use our default id @n.
-- NB, this would also include records when a Person exists with no Detail rows (they are filtered out with the final inner join)
, cteSudoPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
        coalesce(upp.[PersonID],@n) as [PersonID]
        coalesce(upp.[PersonName],udp.[PersonName]) as [PersonName]
    from cteUniquePersonPerson upp
    full outer join cteUniqueDetailPerson udp
        on udp.[PersonName] = p.[PersonName]
)

-- Fourth, join detail to the sudo person table that includes either the original ID or our default ID.
select
      d.[Fields]
    , sp.[PersonID]
from [Details] d
inner join cteSudoPerson sp
    on sp.[PersonName] = d.[PersonName];

您可以使用公共表表达式来构建缺少的数据集,即完整的Person表,然后将其连接到Detail表,如下所示:

declare @n int;
-- set your default PersonID here;
set @n = 123;

-- Make sure previous SQL statement is terminated with semilcolon for with clause to parse successfully.

-- First build our unique list of names from table Detail.
with cteUniqueDetailPerson
(
    [PersonName]
)
as
(
    select distinct [PersonName]
    from [Details]
)

-- Second get unique Person entries and record the most recent PersonID value as the active Person.
, cteUniquePersonPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
          max([PersonID]) -- if you wanted the original Person record instead of the last, change this to min.
        , [PersonName]
    from [Person]
    group by [PersonName]
)

-- Third join unique datasets to get the PersonID when there is a match, otherwise use our default id @n.
-- NB, this would also include records when a Person exists with no Detail rows (they are filtered out with the final inner join)
, cteSudoPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
        coalesce(upp.[PersonID],@n) as [PersonID]
        coalesce(upp.[PersonName],udp.[PersonName]) as [PersonName]
    from cteUniquePersonPerson upp
    full outer join cteUniqueDetailPerson udp
        on udp.[PersonName] = p.[PersonName]
)

-- Fourth, join detail to the sudo person table that includes either the original ID or our default ID.
select
      d.[Fields]
    , sp.[PersonID]
from [Details] d
inner join cteSudoPerson sp
    on sp.[PersonName] = d.[PersonName];

您可以使用公共表表达式来构建缺少的数据集,即完整的Person表,然后将其连接到Detail表,如下所示:

declare @n int;
-- set your default PersonID here;
set @n = 123;

-- Make sure previous SQL statement is terminated with semilcolon for with clause to parse successfully.

-- First build our unique list of names from table Detail.
with cteUniqueDetailPerson
(
    [PersonName]
)
as
(
    select distinct [PersonName]
    from [Details]
)

-- Second get unique Person entries and record the most recent PersonID value as the active Person.
, cteUniquePersonPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
          max([PersonID]) -- if you wanted the original Person record instead of the last, change this to min.
        , [PersonName]
    from [Person]
    group by [PersonName]
)

-- Third join unique datasets to get the PersonID when there is a match, otherwise use our default id @n.
-- NB, this would also include records when a Person exists with no Detail rows (they are filtered out with the final inner join)
, cteSudoPerson
(
      [PersonID]
    , [PersonName]
)
as
(
    select
        coalesce(upp.[PersonID],@n) as [PersonID]
        coalesce(upp.[PersonName],udp.[PersonName]) as [PersonName]
    from cteUniquePersonPerson upp
    full outer join cteUniqueDetailPerson udp
        on udp.[PersonName] = p.[PersonName]
)

-- Fourth, join detail to the sudo person table that includes either the original ID or our default ID.
select
      d.[Fields]
    , sp.[PersonID]
from [Details] d
inner join cteSudoPerson sp
    on sp.[PersonName] = d.[PersonName];

=null
将永远不会计算为true,您需要说
为null
。此外,您使用的模式效率低下且不直观。您应该尝试外部联接,而不是所有这些冗长的子查询。这样编写子查询是一个坏习惯:
(从Person中选择前1个PersonID,其中PersonName=d.PersonName)
-尝试养成在它们内部使用别名的习惯—
(从Person p中选择前1个p.PersonID,其中p.PersonName=d.PersonName)
-如果您得到的列名不正确,但外部查询中存在相同的列,则会在没有警告的情况下使用,这通常是不正确的(例如,如果
Person
中没有
PersonName
列,则您的
WHERE
子句实际上会变成
其中d.PersonName=d.PersonName
)感谢Damien的宝贵意见。
=null
的计算结果永远不会为true,您需要说
为null
。此外,您使用的模式效率低下且不直观。您应该尝试外部联接,而不是所有这些冗长的子查询。这样编写子查询是一个坏习惯:
(从Person中选择前1个PersonID,其中PersonName=d.PersonName)
-尝试养成在它们内部使用别名的习惯—
(从Person p中选择前1个p.PersonID,其中p.PersonName=d.PersonName)
-如果列名不正确,但外部查询中存在相同的列,则将在没有警告的情况下使用该列,这通常是inc